/**
 @file sys_usw_port_api.c

 @author  Copyright (C) 2021 Centec Networks Inc.  All rights reserved.

 @date 2021-11-19

 @version v2.0

*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "sal.h"
#include "dal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_warmboot.h"

#include "sys_usw_common.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_port.h"
#include "sys_usw_phy.h"
#include "sys_usw_dmps_db.h"
#include "sys_usw_peri.h"
#include "sys_usw_register.h"
#include "sys_usw_port_api.h"
#include "sys_usw_scl_api.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dmps.h"
#include "sys_usw_mac.h"

#include "drv_api.h"

/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/
#define PORT_API_LOCK(lchip) \
    if(p_usw_port_api_master[lchip]->p_port_mutex) sal_mutex_lock(p_usw_port_api_master[lchip]->p_port_mutex)

#define PORT_API_UNLOCK(lchip) \
    if(p_usw_port_api_master[lchip]->p_port_mutex) sal_mutex_unlock(p_usw_port_api_master[lchip]->p_port_mutex)

#define SYS_PORT_INIT_CHECK(lchip)                  \
do                                                  \
{                                                   \
    LCHIP_CHECK(lchip);                             \
    if (NULL == p_usw_port_api_master[lchip]){      \
        return CTC_E_NOT_INIT; }                    \
}                                                   \
while (0)

#define SYS_PORT_API_DBG_OUT(level, FMT, ...) \
    do { \
        CTC_DEBUG_OUT(port, api, PORT_API_SYS, level, FMT, ##__VA_ARGS__); \
    } while (0)

extern int32
sys_usw_ip_source_guard_set_default_entry(uint8 lchip, uint16 lport, uint32 gport, uint32 agg_port_cnt, uint16 tid);
extern int32
sys_usw_ip_source_guard_remove_default_entry(uint8 lchip, uint32 gport, uint8 scl_id);
extern uint8
sys_usw_acl_get_league_block(uint8 lchip, uint8 block_id, uint8 * block_list);
extern uint8
sys_usw_acl_build_flow_hash_default_entry(uint8 lchip, uint16 lport, uint8 is_add);
extern int32
sys_usw_mdio_init(uint8 lchip);
extern int32
_sys_usw_dmps_dynamic_switch_set_group_power(uint8 lchip, sys_dmps_ds_list_t* p_list, uint8 enable);
extern int32
_sys_usw_port_get_use_logic_port(uint8 lchip, uint32 gport, uint8* enable, uint32* logicport);

/****************************************************************************
 *
* Global and Declaration
*
*****************************************************************************/


sys_port_api_master_t* p_usw_port_api_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};
/****************************************************************************
 *
* Function
*
*****************************************************************************/

#define ______PORT_PORT_API______

/**
@brief  Set Port MAC PostFix
*/
int32
sys_usw_port_api_set_port_mac_postfix(uint8 lchip, uint32 gport, ctc_port_mac_postfix_t* p_port_mac)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_port_mac);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_port_mac_postfix(lchip, gport, p_port_mac);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
@brief  Get Port MAC
*/
int32
sys_usw_port_api_get_port_mac(uint8 lchip, uint32 gport, mac_addr_t* p_port_mac)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_port_mac);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_get_port_mac(lchip, gport, p_port_mac);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
@brief  Get Port Capability
*/
int32
sys_usw_port_api_get_capability(uint8 lchip, uint32 gport, ctc_port_capability_type_t type, void* p_value)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;

    CTC_PTR_VALID_CHECK(p_value);
    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
    ret = ret?ret:sys_usw_dmps_get_mac_capability(lchip, lport, type, p_value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
@brief  Set Port Capability
*/
int32
sys_usw_port_api_set_capability(uint8 lchip, uint32 gport, ctc_port_capability_type_t type, uint32 value)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
    ret = ret?ret:sys_usw_dmps_set_mac_capability(lchip, lport, type, value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief bind phy_if to port
*/
int32
sys_usw_port_api_set_phy_if_en(uint8 lchip, uint32 gport, bool enable)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    SYS_GLOBAL_PORT_CHECK(gport);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_phy_if_en(lchip, gport, enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief get phy_if whether enable on port
*/
int32
sys_usw_port_api_get_phy_if_en(uint8 lchip, uint32 gport, uint16* p_l3if_id, bool* p_enable)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_enable);
    CTC_PTR_VALID_CHECK(p_l3if_id);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_get_phy_if_en(lchip, gport, p_l3if_id, p_enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief bind phy_if to port
*/
int32
sys_usw_port_api_set_sub_if_en(uint8 lchip, uint32 gport, bool enable)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_sub_if_en(lchip, gport, enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief get phy_if whether enable on port
*/
int32
sys_usw_port_api_get_sub_if_en(uint8 lchip, uint32 gport, bool* p_enable)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_enable);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_get_sub_if_en(lchip, gport, p_enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief set vlan range
*/
int32
sys_usw_port_api_set_vlan_range(uint8 lchip, uint32 gport, ctc_vlan_range_info_t* p_vrange_info, bool enable)
{
    int32 ret = CTC_E_NONE;
    bool is_svlan = FALSE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_vrange_info);
    SYS_VLAN_RANGE_INFO_CHECK(p_vrange_info);
    CTC_MAX_VALUE_CHECK(p_vrange_info->block_id , 1);
    SYS_VLAN_RANGE_EGRESS_BLOCK_ID_CHECK(p_vrange_info);

    if(enable)
    {
        CTC_ERROR_RETURN(sys_usw_vlan_get_vlan_range_type(lchip, p_vrange_info, &is_svlan));
    }

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_vlan_range(lchip, gport, p_vrange_info, is_svlan, enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief get vlan range
*/
int32
sys_usw_port_api_get_vlan_range(uint8 lchip, uint32 gport, ctc_vlan_range_info_t* p_vrange_info, bool* p_enable)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_enable);
    CTC_PTR_VALID_CHECK(p_vrange_info);
    CTC_MAX_VALUE_CHECK(p_vrange_info->block_id , 1);
    CTC_BOTH_DIRECTION_CHECK(p_vrange_info->direction);
    SYS_VLAN_RANGE_EGRESS_BLOCK_ID_CHECK(p_vrange_info);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_get_vlan_range(lchip, gport, p_vrange_info, p_enable);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief Port support 2 loopback modes, efm loopback and crossconnect loopback
*/
int32
sys_usw_port_api_set_loopback(uint8 lchip, ctc_port_lbk_param_t* p_port_lbk)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_port_lbk);
    SYS_GLOBAL_PORT_CHECK(p_port_lbk->src_gport);
    SYS_GLOBAL_PORT_CHECK(p_port_lbk->dst_gport);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_loopback(lchip, p_port_lbk);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief set port min frame size
*/
int32
sys_usw_port_api_set_min_frame_size(uint8 lchip, ctc_frame_size_t index, uint16 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

    if (!MCHIP_PORT(lchip)->port_set_min_frame_size)
    {
        return CTC_E_NONE;
    }

    if (index > CTC_FRAME_SIZE_MAX)
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((value < MCHIP_CAP(SYS_CAP_PORT_MIN_FRAMESIZE_MIN_VALUE)) || (value > MCHIP_CAP(SYS_CAP_PORT_MIN_FRAMESIZE_MAX_VALUE)))
    {
        return CTC_E_INVALID_PARAM;
    }

    if(CTC_FRAME_SIZE_7 == index && SYS_USW_ILOOP_MIN_FRAMESIZE_DEFAULT_VALUE < value )
    {
        return CTC_E_INVALID_PARAM;
    }

	PORT_API_LOCK(lchip);
	ret = MCHIP_PORT(lchip)->port_set_min_frame_size(lchip, index, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief get port min frame size
*/
int32
sys_usw_port_api_get_min_frame_size(uint8 lchip, ctc_frame_size_t index, uint16* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

    if (!MCHIP_PORT(lchip)->port_get_min_frame_size)
    {
        return CTC_E_NONE;
    }

    if (index > CTC_FRAME_SIZE_MAX)
    {
        return CTC_E_INVALID_FRAMESIZE_INDEX;
    }

    CTC_PTR_VALID_CHECK(p_value);

	PORT_API_LOCK(lchip);
	ret = MCHIP_PORT(lchip)->port_get_min_frame_size(lchip, index, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief set port max frame size
*/
int32
sys_usw_port_api_set_max_frame_size(uint8 lchip, ctc_frame_size_t index, uint16 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

    if (!MCHIP_PORT(lchip)->port_set_max_frame_size)
    {
        return CTC_E_NONE;
    }

    if (index > CTC_FRAME_SIZE_MAX)
    {
        return CTC_E_INVALID_FRAMESIZE_INDEX;
    }

    if ((value < MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MIN_VALUE)) || (value > MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE)))
    {
        return CTC_E_INVALID_PARAM;
    }

    if((CTC_FRAME_SIZE_7 == index) && (SYS_USW_MAX_FRAMESIZE_DEFAULT_VALUE > value) )
    {
        return CTC_E_INVALID_PARAM;
    }

	PORT_API_LOCK(lchip);
	ret = MCHIP_PORT(lchip)->port_set_max_frame_size(lchip, index, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief get port max frame size
*/
int32
sys_usw_port_api_get_max_frame_size(uint8 lchip, ctc_frame_size_t index, uint16* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

    if (!MCHIP_PORT(lchip)->port_get_max_frame_size)
    {
        return CTC_E_NONE;
    }

    CTC_PTR_VALID_CHECK(p_value);

    if (index > CTC_FRAME_SIZE_MAX)
    {
        return CTC_E_INVALID_FRAMESIZE_INDEX;
    }

	PORT_API_LOCK(lchip);
	ret = MCHIP_PORT(lchip)->port_get_max_frame_size(lchip, index, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief    Set port's restriction
*/
int32
sys_usw_port_api_set_restriction(uint8 lchip, uint32 gport, ctc_port_restriction_t* p_restriction)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_restriction);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_restriction(lchip, gport, p_restriction);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief    Get port's restriction
*/
int32
sys_usw_port_api_get_restriction(uint8 lchip, uint32 gport, ctc_port_restriction_t* p_restriction)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_restriction);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_restriction(lchip, gport, p_restriction);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set port isolation
*/
int32
sys_usw_port_api_set_isolation(uint8 lchip, ctc_port_isolation_t* p_port_isolation)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_port_isolation);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_isolation(lchip, p_port_isolation);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Get port isolation
*/
int32
sys_usw_port_api_get_isolation(uint8 lchip, ctc_port_isolation_t* p_port_isolation)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_port_isolation);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_isolation(lchip, p_port_isolation);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief  Set ipg size
*/
int32
sys_usw_port_api_set_ipg_size(uint8 lchip, ctc_ipg_size_t index, uint8 size)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_ipg_size(lchip, index, size);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief  Get ipg size
*/
int32
sys_usw_port_api_get_ipg_size(uint8 lchip, ctc_ipg_size_t index, uint8* p_size)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_size);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_ipg_size(lchip, index, p_size);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set scl property to gport
*/
int32
sys_usw_port_api_set_scl_property(uint8 lchip, uint32 gport, ctc_port_scl_property_t* p_prop)
{
	int32 ret = CTC_E_NONE;
    uint16 lport = 0;
    uint8 temp_lchip = 0;
    uint16 class_id = 0;
    uint32 agg_gport = 0;
    uint32 cmd = 0;
    DsPhyPortExt2_m ds2;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
	SYS_PORT_INIT_CHECK(lchip);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    if (DRV_FROM_TMM(lchip) && p_prop->scl_id < 2)
    {
        cmd = DRV_IOR(DsPhyPortExt2_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, &ds2));
        class_id = p_prop->scl_id ? GetDsPhyPortExt2(V, userIdLabel1_f, &ds2) : GetDsPhyPortExt2(V, userIdLabel0_f, &ds2);
    }

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_scl_property(lchip, gport, p_prop);
	PORT_API_UNLOCK(lchip);
    if (CTC_INGRESS == p_prop->direction)
    {
        temp_lchip = lchip;
        SYS_MAP_GPORT_TO_LCHIP1(gport, temp_lchip);
        if (DRV_FROM_TMM(lchip) && p_prop->scl_id < 2)
        {
            if (p_prop->hash_type != CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE)
            {
                class_id = p_prop->class_id;
            }
        }

        if(DRV_IS_TSINGMA(lchip) && p_prop->scl_id < 2)
        {
            sys_usw_port_get_global_port(lchip, lport, &agg_gport);
            if(p_prop->class_id == MCHIP_CAP(SYS_CAP_SCL_LABEL_FOR_IPSG) && \
                (p_prop->hash_type != CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE || p_prop->tcam_type != CTC_PORT_IGS_SCL_TCAM_TYPE_DISABLE))
            {
                ret = sys_usw_ip_source_guard_add_default_entry(lchip, agg_gport, p_prop->scl_id);
                if (CTC_E_ENTRY_EXIST != ret && CTC_E_NONE != ret)
                {
                    return ret;
                }
            }
            else
            {
                sys_usw_ip_source_guard_remove_default_entry(lchip, agg_gport, p_prop->scl_id);
            }
        }
        else if (DRV_FROM_TMM(lchip) && class_id == MCHIP_CAP(SYS_CAP_SCL_LABEL_FOR_IPSG) && (2 > p_prop->scl_id))
        {
            sys_scl_default_action_t sys_default_action;
            ctc_scl_field_action_t   field_action;
            sal_memset(&sys_default_action, 0, sizeof(sys_scl_default_action_t));
            sal_memset(&field_action, 0, sizeof(ctc_scl_field_action_t));

            sys_default_action.action_type = SYS_SCL_ACTION_INGRESS;
            sys_default_action.lport = lport;
            sys_default_action.scl_id = p_prop->scl_id;
            sys_default_action.field_action = &field_action;

            /* set pending status */
            field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
            field_action.data0 = 1;
            CTC_ERROR_RETURN(sys_usw_scl_set_default_action(temp_lchip, &sys_default_action));
            /* set default action discard */
            if (p_prop->hash_type != CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE)
            {
                field_action.type = CTC_SCL_FIELD_ACTION_TYPE_DISCARD;
                CTC_ERROR_RETURN(sys_usw_scl_set_default_action(temp_lchip, &sys_default_action));
            }
            /* reset pending status */
            field_action.type = CTC_SCL_FIELD_ACTION_TYPE_PENDING;
            field_action.data0 = 0;
            CTC_ERROR_RETURN(sys_usw_scl_set_default_action(temp_lchip, &sys_default_action));
        }
        if (DRV_FROM_TMM(lchip) && p_prop->scl_id < 2)
        {
            if (class_id == MCHIP_CAP(SYS_CAP_SCL_LABEL_FOR_VLAN_CLASS))
            {
                CTC_ERROR_RETURN(sys_usw_vlan_class_set_default_action(temp_lchip, lport, p_prop->scl_id, (p_prop->hash_type != CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE)));
            }
            else if (class_id == MCHIP_CAP(SYS_CAP_SCL_LABEL_FOR_SRV6))
            {
                CTC_ERROR_RETURN(MCHIP_SRV6(lchip)->set_gsid_default_action(temp_lchip, lport, (p_prop->hash_type == CTC_PORT_IGS_SCL_HASH_TYPE_DISABLE)));
            }
        }
    }
	return ret;
}

/**
 @brief Get scl property of gport
*/
int32
sys_usw_port_api_get_scl_property(uint8 lchip, uint32 gport, ctc_port_scl_property_t* p_prop)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_scl_property(lchip, gport, p_prop);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set acl property
*/
int32
sys_usw_port_api_set_acl_property(uint8 lchip, uint32 gport, ctc_acl_property_t* p_prop)
{
	int32 ret = CTC_E_NONE;
    uint8  acl_block_id = 0;
    uint8  acl_block_num = 0;
    uint8  league_update_flag = 0;
    uint16 lport = 0;
    uint8  acl_block_list[CTC_MAX_ACL_LKUP_NUM] = {0};

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_prop);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    SYS_ACL_PROPERTY_CHECK(p_prop);
    SYS_USW_MAX_CLASS_ID_CHECK(p_prop->class_id);

    if (CTC_FLAG_ISSET(p_prop->flag, CTC_ACL_PROP_FLAG_USE_PORT_BITMAP)
        + CTC_FLAG_ISSET(p_prop->flag, CTC_ACL_PROP_FLAG_USE_METADATA)
        + CTC_FLAG_ISSET(p_prop->flag, CTC_ACL_PROP_FLAG_USE_LOGIC_PORT) > 1)
    {
        SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Port bitmap Metedata and Logic port can not be configured at the same time \n");
        return CTC_E_NOT_SUPPORT;
    }

    if((CTC_ACL_TCAM_LKUP_TYPE_VLAN == p_prop->tcam_lkup_type) || (DRV_FROM_TMM(lchip) && CTC_FLAG_ISSET(p_prop->flag, CTC_ACL_PROP_FLAG_USE_WLAN)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    acl_block_num = 1;
    acl_block_list[0] = p_prop->acl_priority;
    if (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && (p_prop->direction == CTC_INGRESS)) || DRV_FROM_AT(lchip))
    {
        acl_block_id = (p_prop->direction == CTC_INGRESS)
                        ? p_prop->acl_priority
                        : (p_prop->acl_priority + MCHIP_CAP(SYS_CAP_ACL_INGRESS_LKUP_NUM));
        league_update_flag = MCHIP_ACL(lchip)->get_league_update_flag(lchip, p_prop->direction, 1, 0, 0);
        if (TRUE == league_update_flag)
        {
            acl_block_num = sys_usw_acl_get_league_block(lchip, acl_block_id, acl_block_list);
        }
    }

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_acl_property(lchip, gport, p_prop, acl_block_num, acl_block_list);
	PORT_API_UNLOCK(lchip);

    if(DRV_FROM_AT(lchip) && ((p_prop->acl_en && 5 == p_prop->hash_lkup_type) || !p_prop->acl_en))
    {
        ret = sys_usw_acl_build_flow_hash_default_entry(lchip, lport, p_prop->acl_en);
    }
	return ret;
}

/**
 @brief Get acl property
*/
int32
sys_usw_port_api_get_acl_property(uint8 lchip, uint32 gport, ctc_acl_property_t* p_prop)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_acl_property(lchip, gport, p_prop);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set bpe property
*/
int32
sys_usw_port_api_set_bpe_property(uint8 lchip, uint32 gport, ctc_port_bpe_property_t * p_prop)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_prop);
    CTC_MAX_VALUE_CHECK(p_prop->name_space, (2*1024 - 1));
    CTC_MAX_VALUE_CHECK(p_prop->ecid, 4095);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_bpe_property(lchip, gport, p_prop);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Get bpe property
*/
int32
sys_usw_port_api_get_bpe_property(uint8 lchip, uint32 gport, ctc_port_bpe_property_t* p_prop)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_prop);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_bpe_property(lchip, gport, p_prop);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set port base MAC authentication enable
*/
int32
sys_usw_port_api_set_mac_auth(uint8 lchip, uint32 gport, bool enable)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_mac_auth(lchip, gport, enable);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Get port base MAC authentication
*/
int32
sys_usw_port_api_get_mac_auth(uint8 lchip, uint32 gport, bool* enable)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(enable);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_mac_auth(lchip, gport, enable);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Get port interface mode
*/
int32
sys_usw_port_api_glb_dest_port_init(uint8 lchip, uint16 glb_port_index)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_glb_dest_port_init(lchip, glb_port_index);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_set_glb_dest_port_by_dest_port(uint8 lchip, uint16 lport)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_glb_dest_port_by_dest_port(lchip, lport);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_get_port_reflective(uint8 lchip, uint32* p_bmp)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_bmp);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_port_reflective(lchip, p_bmp);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_update_mc_linkagg(uint8 lchip, uint16 tid, uint16 lport, bool is_add)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_update_mc_linkagg(lchip, tid, lport, is_add);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief set the port global_src_port and global_dest_port in system, the lport means ctc/sys level lport
*/
int32
sys_usw_port_api_set_global_port(uint8 lchip, uint16 lport, uint32 gport, bool update_mc_linkagg)
{
	int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 agg_gport = 0;
    uint32 agg_port_cnt = 0;
    uint16 tid = 0;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    SYS_GLOBAL_PORT_CHECK(gport);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_global_port(lchip, lport, gport, update_mc_linkagg);
    if(!CTC_IS_LINKAGG_PORT(gport))
    {
        sys_usw_port_get_global_port(lchip, lport, &agg_gport);
        if(CTC_IS_LINKAGG_PORT(agg_gport))
        {
            tid = CTC_GPORT_LINKAGG_ID(gport);
            cmd = DRV_IOR(DsLinkAggregateGroup_t, DsLinkAggregateGroup_linkAggMemNum_f);
            DRV_FIELD_IOCTL(lchip, tid, cmd, &agg_port_cnt);
        }
    }
	PORT_API_UNLOCK(lchip);
    if (ret < 0)
    {
        return ret;
    }
    sys_usw_ip_source_guard_set_default_entry(lchip, lport, gport, agg_port_cnt, tid);

	return ret;
}

/**
 @brief get the port global_src_port and global_dest_port in system. Src and dest are equal.
*/
int32
sys_usw_port_api_get_global_port(uint8 lchip, uint16 lport, uint32* p_gport)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_gport);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_global_port(lchip, lport, p_gport);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_get_local_phy_port(uint8 lchip, uint32 gport, uint32* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_local_phy_port(lchip, gport, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_lport_convert(uint8 lchip, uint16 internal_lport, uint16* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_lport_convert(lchip, internal_lport, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_set_isolation_mode(uint8 lchip, uint8 choice_mode)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_isolation_mode(lchip, choice_mode);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_get_isolation_mode(uint8 lchip, uint8* p_choice_mode)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_choice_mode);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_isolation_mode(lchip, p_choice_mode);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief  Config port's internal properties
*/
int32
sys_usw_port_api_set_internal_property(uint8 lchip, uint32 gport, sys_port_internal_property_t port_prop, uint32 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_internal_property(lchip, gport, port_prop, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
@brief  Get port's internal properties according to gport id
*/
int32
sys_usw_port_api_get_internal_property(uint8 lchip, uint32 gport, sys_port_internal_property_t port_prop, uint32* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_internal_property(lchip, gport, port_prop, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_set_mirror_en(uint8 lchip, uint16 lport, uint8 type, uint32 dsfwd_offset, bool is_add)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_mirror_en(lchip, lport, type, dsfwd_offset, is_add);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Set port mac low 8bits
*/
int32
sys_usw_port_api_set_port_mac(uint8 lchip, uint32 gport, mac_addr_t mac_da)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_port_mac(lchip, gport, mac_da);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief Get port mac low 8bits
*/
int32
sys_usw_port_api_set_if_status(uint8 lchip, uint16 lport, uint32 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_if_status(lchip, lport, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_set_scl_hash_tcam_priority(uint8 lchip, uint32 gport, uint8 scl_id, uint8 is_tcam, uint8 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
	CTC_MAX_VALUE_CHECK(scl_id, 1);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_scl_hash_tcam_priority(lchip, gport, scl_id, is_tcam, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_set_acl_league_property(uint8 lchip, uint8 acl_pri, uint8 enable, uint8 sub_blk_cnt, uint8 *sub_blk_list)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_acl_league_property(lchip, acl_pri, enable, sub_blk_cnt, sub_blk_list);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_register_rchip_get_gport_idx_cb(uint8 lchip, SYS_PORT_GET_RCHIP_GPORT_IDX_CB cb)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_register_rchip_get_gport_idx_cb(lchip, cb);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief set the port default configure
*/
int32
sys_usw_port_api_set_default_cfg(uint8 lchip, uint32 gport)
{
    int32 ret = CTC_E_NONE;
    uint32 lport = 0;
    uint32 agg_port_cnt = 0;
    uint16 tid = 0;
    uint32 cmd = 0;
    uint32 agg_gport = 0;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_default_cfg(lchip, gport);

    /*do write table*/
    if(!CTC_IS_LINKAGG_PORT(gport))
    {
        sys_usw_port_get_global_port(lchip, lport, &agg_gport);
        if(CTC_IS_LINKAGG_PORT(agg_gport))
        {
            tid = CTC_GPORT_LINKAGG_ID(gport);
            cmd = DRV_IOR(DsLinkAggregateGroup_t, DsLinkAggregateGroup_linkAggMemNum_f);
            DRV_FIELD_IOCTL(lchip, tid, cmd, &agg_port_cnt);
        }
    }
    PORT_API_UNLOCK(lchip);

    ret = ret ? ret : sys_usw_ip_source_guard_set_default_entry(lchip, lport, gport, agg_port_cnt, tid);
    ret = ret ? ret : sys_usw_brguc_nh_create(lchip, gport, CTC_NH_PARAM_BRGUC_SUB_TYPE_ALL);
    if (CTC_E_EXIST != ret && CTC_E_NONE != ret)
    {
        return ret;
    }
    return CTC_E_NONE;
}

/**
 @brief   Config port's properties
*/
int32
sys_usw_port_api_set_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, uint32 value)
{
    int32 ret = 0;
    uint16 lport = 0;
    uint32 cmd = 0;
    uint32 agg_gport = 0;
    uint32 agg_port_cnt = 0;
    uint16 tid = 0;
    uint32  field = 0;
    uint32 logic_port = 0;
    uint8 enable = 0;
    sys_qos_shape_profile_t shp_profile;
    uint8 port_flush_en = 0;
    SYS_PORT_INIT_CHECK(lchip);

    sal_memset(&shp_profile, 0, sizeof(sys_qos_shape_profile_t));
    if (CTC_PORT_PROP_XPIPE_EN == port_prop || CTC_PORT_PROP_XPIPE_MODE == port_prop)
    {
        ret = sys_usw_port_check_xpipe(lchip, gport, port_prop, value);
        if(ret)
        {
            return ((CTC_E_EXIST == ret) ? CTC_E_NONE : ret);
        }
        port_flush_en = ((CTC_PORT_PROP_XPIPE_EN == port_prop && CTC_PORT_XPIPE_TYPE_4 != value && CTC_PORT_XPIPE_TYPE_5 != value) 
                      || (CTC_PORT_PROP_XPIPE_MODE == port_prop && (DRV_FROM_AT(lchip) || CTC_XPIPE_MODE_0 == value))) ? 1 : 0;

        if (port_flush_en)
        {
            /*for restore shape profile*/
            if (!DRV_FROM_TMM(lchip))
            {
                CTC_ERROR_RETURN(sys_usw_queue_get_profile_from_hw(lchip, gport, &shp_profile));
            }
            CTC_ERROR_RETURN(sys_usw_queue_set_port_drop_en(lchip, gport, TRUE, &shp_profile));
            CTC_ERROR_GOTO(sys_usw_common_check_port_status(lchip, gport, &shp_profile), ret, roll_back);
        }
    }

    PORT_API_LOCK(lchip);
     if (CTC_PORT_PROP_GPORT == port_prop)
     {
         lport = SYS_MAP_CTC_GPORT_TO_DRV_LPORT(gport);
         if(!CTC_IS_LINKAGG_PORT(value))
         {
             sys_usw_port_get_global_port(lchip, lport, &agg_gport);
             if(CTC_IS_LINKAGG_PORT(agg_gport))
             {
                 tid = CTC_GPORT_LINKAGG_ID(gport);
                 cmd = DRV_IOR(DsLinkAggregateGroup_t, DsLinkAggregateGroup_linkAggMemNum_f);
                 DRV_FIELD_IOCTL(lchip, tid, cmd, &agg_port_cnt);
             }
         }
     }
     if ((CTC_PORT_PROP_MAC_EN == port_prop)
        || (CTC_PORT_PROP_FEC_EN == port_prop)
        || (CTC_PORT_PROP_SIGNAL_DETECT == port_prop)
        || (CTC_PORT_PROP_LINK_INTRRUPT_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_MODE == port_prop)
        || (CTC_PORT_PROP_SPEED == port_prop)
        || (CTC_PORT_PROP_PREAMBLE == port_prop)
        || (CTC_PORT_PROP_ERROR_CHECK == port_prop)
        || (CTC_PORT_PROP_PADING_EN == port_prop)
        || (CTC_PORT_PROP_RX_PAUSE_TYPE == port_prop)
        || (CTC_PORT_PROP_LINKSCAN_EN == port_prop)
        || (CTC_PORT_PROP_UNIDIR_EN == port_prop)
        || (CTC_PORT_PROP_MAC_TX_IPG == port_prop)
        || (CTC_PORT_PROP_CL73_ABILITY == port_prop)
        || (CTC_PORT_PROP_CHK_CRC_EN == port_prop)
        || (CTC_PORT_PROP_STRIP_CRC_EN == port_prop)
        || (CTC_PORT_PROP_APPEND_CRC_EN == port_prop)
        || (CTC_PORT_PROP_APPEND_TOD_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_FEC == port_prop)
        || (CTC_PORT_PROP_FEC_CNT == port_prop)
        || (CTC_PORT_PROP_MAC_TS_EN == port_prop)
        || (CTC_PORT_PROP_FAULT == port_prop)
        || (CTC_PORT_PROP_PAR_DET_EN == port_prop)
        || (CTC_PORT_PROP_LINK_UP == port_prop)
        || (CTC_PORT_PROP_EEE_EN == port_prop)
        || (CTC_PORT_PROP_FEC_ERR_INJECT == port_prop))
        {
            ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
            ret = ret?ret:sys_usw_dmps_set_mac_property(lchip, lport, port_prop, value);
        }
    else if ((CTC_PORT_PROP_PHY_INIT == port_prop)
        || (CTC_PORT_PROP_PHY_EN == port_prop)
        || (CTC_PORT_PROP_PHY_DUPLEX == port_prop)
        || (CTC_PORT_PROP_PHY_MEDIUM == port_prop)
        || (CTC_PORT_PROP_PHY_LOOPBACK == port_prop)
        || (CTC_PORT_PROP_PHY_AUTO_NEG_EN == port_prop)
        || (CTC_PORT_PROP_PHY_SPEED == port_prop))
    {
        ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
        ret = ret?ret:sys_usw_phy_set_phy_property(lchip, lport, port_prop, (void*)&value);
    }
    else
    {
        ret = sys_usw_port_set_property(lchip, gport, port_prop, value);
    }
    if (DRV_FROM_AT(lchip) && CTC_PORT_PROP_XPIPE_EN == port_prop && value)
    {
        uint32 frame_size = 0;
        /*max frame size*/
        ret= ret? ret: sys_usw_port_get_property(lchip, gport, CTC_PORT_PROP_MAX_FRAME_SIZE, &frame_size);
        ret = ret? ret : sys_usw_port_set_property(lchip, gport, CTC_PORT_PROP_MAX_FRAME_SIZE, frame_size);
        /*min frame size*/
        ret= ret? ret: sys_usw_port_get_property(lchip, gport, CTC_PORT_PROP_MIN_FRAME_SIZE, &frame_size);
        ret = ret? ret : sys_usw_port_set_property(lchip, gport, CTC_PORT_PROP_MIN_FRAME_SIZE, frame_size);
    }
    PORT_API_UNLOCK(lchip);
    if (CTC_PORT_PROP_GPORT == port_prop)
    {
        ret= ret? ret: sys_usw_ip_source_guard_set_default_entry(lchip, lport, gport, agg_port_cnt, tid);
    }
    else if (CTC_PORT_PROP_XPIPE_EN == port_prop || CTC_PORT_PROP_XPIPE_MODE == port_prop)
    {
        if(ret)
        {
            goto roll_back;
        }
#ifdef ARCTIC
        if ( CTC_PORT_PROP_XPIPE_MODE == port_prop && CTC_XPIPE_MODE_0 != value && DRV_FROM_AT(lchip))
        {
            uint8  index     = 0;
            uint8  chan_num  = 0;
            uint16 lport     = 0;
            uint32 chan_id[SYS_USW_MAX_CHANEL_NUM_PER_PORT] = {0};    /* 0: low prio channel(origin channel), 1: middle prio channel 2: high prio channel */

            lport = CTC_MAP_GPORT_TO_LPORT(gport);

            CTC_ERROR_GOTO(sys_usw_port_api_get_channel(lchip, 0, gport, chan_id, &chan_num), ret, roll_back);
            for (index = 1; index < chan_num; index++)
            {
                CTC_ERROR_GOTO(SYS_CB(SYS_CB_QOS_SET_PORT_DYNAMIC_SWITCH, lchip, lport, index), ret, roll_back);
            }
        }
#endif
        if (port_flush_en)
        {
            /* rollback */
            CTC_ERROR_DUMP(sys_usw_queue_set_port_drop_en(lchip, gport, FALSE, &shp_profile));
        }
    }
    else if (CTC_PORT_PROP_PORT_EN == port_prop)
    {
        ret = ret? ret: (value? sys_usw_brguc_nh_create(lchip, gport, CTC_NH_PARAM_BRGUC_SUB_TYPE_BASIC): CTC_E_NONE);
        if (CTC_E_EXIST != ret && CTC_E_NONE != ret)
        {
            return ret;
        }
    }
    else if (CTC_PORT_PROP_STATION_MOVE_ACTION == port_prop || CTC_PORT_PROP_STATION_MOVE_PRIORITY == port_prop)
    {
        field = (CTC_PORT_PROP_STATION_MOVE_ACTION == port_prop) ? ((value == CTC_PORT_STATION_MOVE_ACTION_TYPE_DISCARD_TOCPU) ? 1 : value): (value);
        _sys_usw_port_get_use_logic_port(lchip, gport, &enable, &logic_port);
        CTC_ERROR_RETURN(sys_usw_l2_set_station_move(lchip, gport, port_prop, logic_port, enable, field));
    }
    return ret;

roll_back:
    if (port_flush_en)
    {
        CTC_ERROR_DUMP(sys_usw_queue_set_port_drop_en(lchip, gport, FALSE, &shp_profile));
    }
    return ret;
}

/**
 @brief    Get port's properties according to gport id
*/
int32
sys_usw_port_api_get_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, uint32* p_value)
{
    int32 ret = 0;
    uint16 lport = 0;

    CTC_PTR_VALID_CHECK(p_value);
    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    if ((CTC_PORT_PROP_MAC_EN == port_prop)
        || (CTC_PORT_PROP_FEC_EN == port_prop)
        || (CTC_PORT_PROP_SIGNAL_DETECT == port_prop)
        || (CTC_PORT_PROP_LINK_INTRRUPT_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_MODE == port_prop)
        || (CTC_PORT_PROP_SPEED == port_prop)
        || (CTC_PORT_PROP_PREAMBLE == port_prop)
        || (CTC_PORT_PROP_ERROR_CHECK == port_prop)
        || (CTC_PORT_PROP_PADING_EN == port_prop)
        || (CTC_PORT_PROP_RX_PAUSE_TYPE == port_prop)
        || (CTC_PORT_PROP_LINKSCAN_EN == port_prop)
        || (CTC_PORT_PROP_UNIDIR_EN == port_prop)
        || (CTC_PORT_PROP_MAC_TX_IPG == port_prop)
        || (CTC_PORT_PROP_CL73_ABILITY == port_prop)
        || (CTC_PORT_PROP_CHK_CRC_EN == port_prop)
        || (CTC_PORT_PROP_STRIP_CRC_EN == port_prop)
        || (CTC_PORT_PROP_APPEND_CRC_EN == port_prop)
        || (CTC_PORT_PROP_APPEND_TOD_EN == port_prop)
        || (CTC_PORT_PROP_AUTO_NEG_FEC == port_prop)
        || (CTC_PORT_PROP_FEC_CNT == port_prop)
        || (CTC_PORT_PROP_MAC_TS_EN == port_prop)
        || (CTC_PORT_PROP_FAULT == port_prop)
        || (CTC_PORT_PROP_PAR_DET_EN == port_prop)
        || (CTC_PORT_PROP_LINK_UP == port_prop)
        || (CTC_PORT_PROP_EEE_EN == port_prop)
        || (CTC_PORT_PROP_FEC_ERR_INJECT == port_prop))
        {
            ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
            ret = ret?ret:sys_usw_dmps_get_mac_property(lchip, lport, port_prop, p_value);
        }
    else if ((CTC_PORT_PROP_PHY_INIT == port_prop)
        || (CTC_PORT_PROP_PHY_EN == port_prop)
        || (CTC_PORT_PROP_PHY_DUPLEX == port_prop)
        || (CTC_PORT_PROP_PHY_MEDIUM == port_prop)
        || (CTC_PORT_PROP_PHY_LOOPBACK == port_prop)
        || (CTC_PORT_PROP_PHY_AUTO_NEG_EN == port_prop)
        || (CTC_PORT_PROP_PHY_SPEED == port_prop))
    {
        ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
        ret = ret?ret:sys_usw_phy_get_phy_property(lchip, lport, port_prop, (void*)p_value);
    }
    else
    {
        ret = sys_usw_port_get_property(lchip, gport, port_prop, p_value);
    }
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief  Get port chan id and chan num according to gport id
*/
int32
sys_usw_port_api_get_channel(uint8 lchip, uint8 rx, uint32 gport, uint32 *chan, uint8 *chan_num)
{
    int32 ret = 0;

    CTC_PTR_VALID_CHECK(chan);
    CTC_PTR_VALID_CHECK(chan_num);
    ret = sys_usw_port_get_channel(lchip, rx, gport, chan, chan_num);

    return ret;
}

/**
 @brief  Get port mac id and mac num according to gport id
*/
int32
sys_usw_port_api_get_mac(uint8 lchip, uint8 rx, uint32 gport, uint32 *mac, uint8 *mac_num)
{
    int32 ret = 0;

    CTC_PTR_VALID_CHECK(mac);
    CTC_PTR_VALID_CHECK(mac_num);
    ret = sys_usw_port_get_mac(lchip, rx, gport, mac, mac_num);

    return ret;
}

/**
 @brief  Set port's internal properties with direction according to gport id
*/
int32
sys_usw_port_api_set_direction_property(uint8 lchip, uint32 gport, ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32 value)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_set_direction_property(lchip, gport, port_prop, dir, value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief  Get port's properties with direction according to gport id
*/
int32
sys_usw_port_api_get_direction_property(uint8 lchip, uint32 gport, ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32* p_value)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_port_get_direction_property(lchip, gport, port_prop, dir, p_value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief  Set port's internal properties with direction according to gport id
*/
int32
sys_usw_port_api_set_internal_direction_property(uint8 lchip, uint32 gport, sys_port_internal_direction_property_t port_prop, ctc_direction_t dir, uint32 value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_internal_direction_property(lchip, gport, port_prop, dir, value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief  Get port's internal properties with direction according to gport id
*/
int32
sys_usw_port_api_get_internal_direction_property(uint8 lchip, uint32 gport, sys_port_internal_direction_property_t port_prop, ctc_direction_t dir, uint32* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_internal_direction_property(lchip, gport, port_prop, dir, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_dump_db(uint8 lchip, sal_file_t dump_db_fp,ctc_global_dump_db_t* p_dump_param)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_dump_db(lchip, dump_db_fp, p_dump_param);
	PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief  Set port's internal properties with direction according to gport id
*/
int32
sys_usw_port_api_set_logic_port_property(uint8 lchip,uint32 logic_port,ctc_logic_port_property_t logic_port_prop,ctc_direction_t dir,void* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_set_logic_port_property(lchip, logic_port, logic_port_prop, dir, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

/**
 @brief  Get port's internal properties with direction according to gport id
*/
int32
sys_usw_port_api_get_logic_port_property(uint8 lchip,uint32 logic_port,ctc_logic_port_property_t logic_port_prop,ctc_direction_t dir,void* p_value)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    SYS_PORT_INIT_CHECK(lchip);

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_get_logic_port_property(lchip, logic_port, logic_port_prop, dir, p_value);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
sys_usw_port_api_wb_sync(uint8 lchip, uint32 app_id)
{
    int32 ret = CTC_E_NONE;

	PORT_API_LOCK(lchip);
	ret = sys_usw_port_wb_sync(lchip, app_id);
	PORT_API_UNLOCK(lchip);

    return ret;
}

#define ______PORT_PHY_API______
/**
 @brief Set phy to port mapping
*/
int32
sys_usw_port_api_set_phy_mapping(uint8 lchip, ctc_chip_phy_mapping_para_t* phy_mapping_para)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(phy_mapping_para);

    ret = sys_usw_phy_set_phy_mapping(lchip, phy_mapping_para);
    return ret;
}

/**
 @brief Get phy to port mapping
*/
int32
sys_usw_port_api_get_phy_mapping(uint8 lchip, ctc_chip_phy_mapping_para_t* phy_mapping_para)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(phy_mapping_para);

    ret = sys_usw_phy_get_phy_mapping(lchip, phy_mapping_para);
    return ret;
}

STATIC void
_sys_usw_port_phy_link_event_polling_cb(uint8 lchip)
{
    uint8 gchip = 0;
    uint32 gport = 0;
    uint32 lport = 0;

    sys_usw_get_gchip_id(lchip, &gchip);

    PORT_API_LOCK(lchip);
    for (lport = 0; lport < SYS_PHY_PORT_NUM_PER_SLICE; lport++)
    {
        if (sys_usw_chip_check_active(lchip) < 0)
        {
            goto end;
        }
        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        sys_usw_phy_link_event_polling_cb(lchip, gport);
    }
end:
    PORT_API_UNLOCK(lchip);
    return;
}


STATIC void
_sys_usw_port_phy_link_event_polling(void* p_data)
{
    uint32 value = 0;
    uint8 lchip = 0;
    uint16 interval = 0;

    value = (uintptr)p_data;
    lchip = value&0xFF;
    interval = (value>>8)&0xFFFF;
    while (1)
    {
        SYS_LCHIP_CHECK_ACTIVE_IN_THREAD(lchip);
        SYS_CHIP_CHECK_RESET_HW_IN_THREAD(lchip);

        if (CTC_WB_STATUS(lchip) != CTC_WB_STATUS_SYNC)
        {
            _sys_usw_port_phy_link_event_polling_cb(lchip);
        }
        sal_task_sleep(interval);
    }

    return;
}

STATIC int32
_sys_usw_port_phy_link_monitor(uint8 lchip, uint16 interval)
{
    drv_work_platform_type_t platform_type;
    int32 ret = 0;
    char buffer[SAL_TASK_MAX_NAME_LEN]={0};
    uint32 value = 0;

    CTC_ERROR_RETURN(drv_get_platform_type(lchip, &platform_type));
    if (platform_type != HW_PLATFORM)
    {
        return CTC_E_NONE;
    }

    sal_sprintf(buffer, "ctcphyMon-%d", lchip);
    value = (interval<<8|lchip);
    if (NULL == p_usw_port_api_master[lchip]->p_polling_scan)
    {
        ret = sal_task_create(&(p_usw_port_api_master[lchip]->p_polling_scan), buffer,
                              SAL_DEF_TASK_STACK_SIZE, SAL_TASK_PRIO_DEF, _sys_usw_port_phy_link_event_polling, (void*)(uintptr)value);
        if (ret < 0)
        {
            return CTC_E_NOT_INIT;
        }
    }
    return CTC_E_NONE;
}


STATIC void
_sys_usw_port_phy_link_event_interrupt_cb(void* p_data)
{
    uint32 irq = *((uint32*)p_data);
    uint16 lchip_num = 0;
    uint16 lchip_idx = 0;
    uint8 lchip = 0;

    /* get lchip num */
    lchip_num = sys_usw_get_local_chip_num();

    for (lchip_idx=0; lchip_idx<lchip_num; lchip_idx++)
    {
        lchip = CTC_MAP_LCHIP(lchip_idx);
        _sys_usw_port_phy_link_event_polling_cb(lchip);
    }

    if (g_dal_op.interrupt_set_en)
    {
        g_dal_op.interrupt_set_en(irq, TRUE);
    }

    return;
}

STATIC int32
_sys_usw_port_unregister_phy(uint8 lchip, ctc_chip_phy_shim_t* p_register)
{
    uint8 idx_tmp = 0;

    if(p_usw_port_api_master[lchip]->p_polling_scan)
    {
        sal_task_destroy(p_usw_port_api_master[lchip]->p_polling_scan);
    }

    if (CTC_CHIP_PHY_SHIM_EVENT_MODE_IRQ == p_register->event_mode)
    {
        for (idx_tmp=0; idx_tmp<CTC_CHIP_PHY_MAX_IRQ_NUM && (0 != p_register->irq[idx_tmp]); idx_tmp++)
        {
            g_dal_op.interrupt_unregister(p_register->irq[idx_tmp]);
        }
    }
    else if (CTC_CHIP_PHY_SHIM_EVENT_MODE_SCAN == p_register->event_mode)
    {
        sys_usw_peri_set_phy_scan_en(lchip, FALSE);
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_port_register_phy(uint8 lchip, ctc_chip_phy_shim_t* p_register)
{
    uint16 poll_interval = 0;
    int32 ret = CTC_E_NONE;
    uint8 idx = 0;
    uint8 idx_tmp = 0;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_register);
    CTC_MAX_VALUE_CHECK(p_register->event_mode, CTC_CHIP_PHY_SHIM_EVENT_MODE_POLLING);
    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "registe phy name %s phy id 0x%x\n", p_register->phy_name, p_register->phy_id);

    if (CTC_CHIP_PHY_SHIM_EVENT_MODE_IRQ == p_register->event_mode)
    {
        for (idx=0; idx<CTC_CHIP_PHY_MAX_IRQ_NUM && (0 != p_register->irq[idx]); idx++)
        {
            SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "register phy irq, irq:%d \n", p_register->irq[idx]);
            ret = g_dal_op.interrupt_register(p_register->irq[idx], SAL_TASK_PRIO_DEF, _sys_usw_port_phy_link_event_interrupt_cb, (void*)(uintptr)(CTC_INTR_MAX_GROUP-idx-1));
            if (ret < 0)
            {
                SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "register phy interrupt failed!! irq:%d \n", p_register->irq[idx]);
                ret = CTC_E_NOT_EXIST;
                goto rollback_0;
            }
        }
    }
    else if (CTC_CHIP_PHY_SHIM_EVENT_MODE_SCAN == p_register->event_mode)
    {
        SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "register phy with mdio scan\n");
        sys_usw_peri_set_phy_scan_en(lchip, TRUE);
    }
    poll_interval = (CTC_CHIP_PHY_SHIM_EVENT_MODE_POLLING== p_register->event_mode)?p_register->poll_interval: 1000;
    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "register phy with polling, timer:%d \n", poll_interval);
    CTC_ERROR_GOTO(_sys_usw_port_phy_link_monitor(lchip, poll_interval), ret, rollback_0);

    return CTC_E_NONE;

rollback_0:
    if (CTC_CHIP_PHY_SHIM_EVENT_MODE_IRQ == p_register->event_mode)
    {
        for (idx_tmp=0; idx_tmp<idx; idx_tmp++)
        {
            g_dal_op.interrupt_unregister(p_register->irq[idx_tmp]);
        }
    }
    else if (CTC_CHIP_PHY_SHIM_EVENT_MODE_SCAN == p_register->event_mode)
    {
        sys_usw_peri_set_phy_scan_en(lchip, FALSE);
    }
    return ret;
}

int32
sys_usw_port_api_register_phy(uint8 lchip, void* p_register)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_register);

    PORT_API_LOCK(lchip);
    CTC_ERROR_GOTO(_sys_usw_port_register_phy(lchip, (ctc_chip_phy_shim_t*)p_register), ret, rollback_0);

    CTC_ERROR_GOTO(sys_usw_phy_set_phy_register(lchip, (ctc_chip_phy_shim_t*)p_register), ret, rollback_1);
    PORT_API_UNLOCK(lchip);

    return CTC_E_NONE;
rollback_1:
    _sys_usw_port_unregister_phy(lchip, p_register);
rollback_0:
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief Set port phy property
*/
int32
sys_usw_port_api_set_phy_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, void* p_value)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
    ret = ret?ret:sys_usw_phy_set_phy_property(lchip, lport, port_prop, p_value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief Get port phy property
*/
int32
sys_usw_port_api_get_phy_property(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, void* p_value)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
    ret = ret?ret:sys_usw_phy_get_phy_property(lchip, lport, port_prop, p_value);
    PORT_API_UNLOCK(lchip);

    return ret;
}

#define ______PORT_DMPS_API______

/**
 @brief Set port property ext
*/
int32
sys_usw_port_api_set_property_ext(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, void* p_value)
{
    int32 ret = 0;
    uint16 lport = 0;

    SYS_PORT_INIT_CHECK(lchip);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    PORT_API_LOCK(lchip);

    switch(port_prop)
    {
        case CTC_PORT_PROP_LINK_INFO:
            CTC_ERROR_GOTO(sys_usw_dmps_port_set_link_info(lchip, lport, p_value), ret, rollback_0);
            break;
        case CTC_PORT_PROP_FEC_ERR_INJECT:
            CTC_ERROR_GOTO(sys_usw_dmps_port_set_err_inject(lchip, lport, p_value), ret, rollback_0);
            break;
        case CTC_PORT_PROP_CL73_ABILITY:
            CTC_ERROR_GOTO(sys_usw_dmps_port_set_cl73_ability_ext(lchip, lport, p_value), ret, rollback_0);
            break;
        default:
            ret = CTC_E_NOT_SUPPORT;
            goto rollback_0;
    }

rollback_0:
    PORT_API_UNLOCK(lchip);
    return ret;
}

/**
 @brief Get port property ext
*/
int32
sys_usw_port_api_get_property_ext(uint8 lchip, uint32 gport, ctc_port_property_t port_prop, void* p_value)
{
    int32 ret = 0;
    uint16 lport = 0;

    SYS_PORT_INIT_CHECK(lchip);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    PORT_API_LOCK(lchip);
    switch(port_prop)
    {
        case CTC_PORT_PROP_LINK_INFO:
            CTC_ERROR_GOTO(sys_usw_dmps_port_get_link_info(lchip, lport, p_value), ret, rollback_0);
            break;
        case CTC_PORT_PROP_FEC_ERR_INJECT:
            CTC_ERROR_GOTO(sys_usw_dmps_port_get_err_inject(lchip, lport, p_value), ret, rollback_0);
            break;
        default:
            ret = CTC_E_NOT_SUPPORT;
            goto rollback_0;
    }

rollback_0:
    PORT_API_UNLOCK(lchip);
    return ret;
}

/**
 @brief Get port mac link up status
*/
int32
sys_usw_port_api_get_mac_link_up(uint8 lchip, uint32 gport, uint32* p_is_up)
{
    int32 ret = CTC_E_NONE;
    uint16 lport = 0;
    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_is_up);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport);
    ret = ret?ret:sys_usw_dmps_get_mac_property(lchip, lport, CTC_PORT_PROP_LINK_UP, p_is_up);
    PORT_API_UNLOCK(lchip);

    return ret;
}

/**
 @brief Set port interface mode
*/
extern int32
_sys_usw_add_port_to_channel(uint8 lchip, uint32 lport, uint16 channel);
int32
_sys_usw_port_api_set_mode_config_attach(uint8 lchip, sys_dmps_ds_list_t* p_list)
{
    uint8  idx   = 0;
    uint16 chan  = DMPS_INVALID_VALUE_U16;
    uint16 dport = DMPS_INVALID_VALUE_U16;
    sys_usw_port_mac_config_t port_mac_cfg = {0};
    sys_dmps_db_upt_info_t    port_info    = {0};

    for(idx = 0; idx < p_list->dst_dport_num; idx++)
    {
        dport = p_list->dst_dport_list[idx];
        port_mac_cfg.lport = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info,      DMPS_DB_CHAN_ID,         chan);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_TYPE,    port_mac_cfg.interface_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, port_mac_cfg.speed_mode);

        CTC_ERROR_RETURN(sys_usw_port_mac_config_attach(lchip, &port_mac_cfg));
		if(DRV_IS_TMG(lchip))
		{
            CTC_ERROR_RETURN(_sys_usw_add_port_to_channel(lchip, port_mac_cfg.lport, chan));
		}
    }

    return CTC_E_NONE;
}

int32
_sys_usw_port_api_set_mode(uint8 lchip, sys_dmps_ds_list_t* ds_list, uint32 option_bmp)
{
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_group_power(lchip, ds_list, SYS_DMPS_DYN_BEFORE_CFG));
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_property_clear(lchip, ds_list, option_bmp));
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_config(lchip, ds_list, option_bmp));
    CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_set_group_power(lchip, ds_list, SYS_DMPS_DYN_AFTER_CFG));
    CTC_ERROR_RETURN(_sys_usw_port_api_set_mode_config_attach(lchip, ds_list));

    return CTC_E_NONE;
}

int32
_sys_usw_port_api_set_interface_mode(uint8 lchip, uint32 gport, ctc_port_if_mode_t* if_mode)
{
    uint8  mode_new    = CTC_CHIP_SERDES_NONE_MODE;
    uint8  mode_old    = CTC_CHIP_SERDES_NONE_MODE;
    uint16 lport       = 0;
    uint32 option_bmp  = 0;
    sys_dmps_ds_list_t ds_list = {0};

    CTC_PTR_VALID_CHECK(if_mode);

    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_SERDES_SWITCH);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_MAC);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_CL73);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_AN_FEC);
    
    CTC_ERROR_RETURN(sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport));
    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_mac_set_interface_mode(lchip, lport, if_mode));
    }
    else
    {
        SYS_DMPS_GET_SERDES_MODE_BY_IFMODE(if_mode->speed, if_mode->interface_type, mode_new);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_ifmode(lchip, lport, &mode_old));
        if(mode_old == mode_new)
        {
            return CTC_E_NONE;
        }
        CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_get_list(lchip, lport, if_mode, &ds_list));
        CTC_ERROR_RETURN(_sys_usw_port_api_set_mode(lchip, &ds_list, option_bmp));
    }

    return CTC_E_NONE;
}

int32
sys_usw_port_api_set_interface_mode(uint8 lchip, uint32 gport, ctc_port_if_mode_t* if_mode)
{
    int32  ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);
    PORT_API_LOCK(lchip);
    ret = _sys_usw_port_api_set_interface_mode(lchip, gport, if_mode);
    PORT_API_UNLOCK(lchip);

    return ret;
}

int32
_sys_usw_port_api_get_interface_mode(uint8 lchip, uint32 gport, ctc_port_if_mode_t* if_mode)
{
    uint16 lport     = 0;
	uint32 port_type = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_PORT_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if (!((SYS_DMPS_NETWORK_PORT == port_type) || (SYS_DMPS_CPU_MAC_PORT == port_type) ||
        (SYS_DMPS_CPUMAC_NETWORK_PORT == port_type) || (SYS_DMPS_INACTIVE_NETWORK_PORT == port_type)))
    {
        return CTC_E_INVALID_PORT;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_gport_map_to_lport_with_check(lchip, gport, &lport));
    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_get_interface_mode(lchip, lport, if_mode));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_interface_mode(lchip, lport, if_mode));
    }

    return CTC_E_NONE;
}


int32
sys_usw_port_api_get_interface_mode(uint8 lchip, uint32 gport, ctc_port_if_mode_t* if_mode)
{
	int32 ret = CTC_E_NONE;

    SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

	SYS_PORT_INIT_CHECK(lchip);
	CTC_PTR_VALID_CHECK(if_mode);

	PORT_API_LOCK(lchip);
	ret = _sys_usw_port_api_get_interface_mode(lchip, gport, if_mode);
	PORT_API_UNLOCK(lchip);

	return ret;
}

int32
_sys_usw_port_api_set_serdes_mode(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info)
{
    uint8  if_mode     = CTC_CHIP_MAX_SERDES_MODE;
    uint8  fec_type    = SYS_DMPS_IS_PAM4_MODE(p_serdes_info->serdes_mode) ? SYS_DMPS_FEC_TYPE_RS544 : SYS_DMPS_FEC_TYPE_NONE;
    uint32 speed_val   = 0;
    uint32 speed       = SERDES_SPEED_MAX;
    uint32 option_bmp  = 0;
    sys_dmps_ds_list_t ds_list = {0};

    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_SERDES_SWITCH);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_MAC);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_CL73);
    CTC_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_AN_FEC);

    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_mode(lchip, p_serdes_info));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_serdes_speed(lchip, p_serdes_info->serdes_id, &speed_val));
        SYS_USW_SERDES_VALUE_2_SPEED(speed_val, speed);
        if (CTC_E_NONE != sys_usw_dmps_db_get_ifmode_by_psd(lchip, p_serdes_info->serdes_id, &if_mode))
        {
            if_mode = CTC_CHIP_SERDES_NONE_MODE;
        }
        if((p_serdes_info->serdes_mode == if_mode) && 
           (speed == sys_usw_dmps_get_speed_from_serdes_info(p_serdes_info->serdes_mode, fec_type, p_serdes_info->overclocking_speed)))
        {
            return CTC_E_NONE;
        }
        CTC_ERROR_RETURN(_sys_usw_dmps_dynamic_switch_serdes_get_list(lchip, p_serdes_info, &ds_list));
        CTC_ERROR_RETURN(_sys_usw_port_api_set_mode(lchip, &ds_list, option_bmp));
    }

    return CTC_E_NONE;
}

int32
sys_usw_port_api_set_serdes_mode(uint8 lchip, ctc_chip_serdes_info_t* p_serdes_info)
{
    int32  ret         = CTC_E_NONE;
    uint16 serdes_id   = 0;
    uint16 psd         = 0;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_serdes_info);

    /* user_serdes to physical_serdes */
    if (MCHIP_DMPS(lchip)->serdes_to_psd)
    {
        serdes_id = p_serdes_info->serdes_id;
        CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
        p_serdes_info->serdes_id = psd;
    }

    PORT_API_LOCK(lchip);
    ret =_sys_usw_port_api_set_serdes_mode(lchip, p_serdes_info);
    PORT_API_UNLOCK(lchip);

    return ret;
}

int32
sys_usw_port_api_set_serdes_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    int32  ret       = CTC_E_NONE;
    uint16 cnt       = 0;
    uint16 serdes_id = 0;
    uint16 psd       = 0;
    ctc_chip_serdes_prbs_t* p_prbs         = (ctc_chip_serdes_prbs_t*)p_value;
    ctc_chip_serdes_ffe_t* p_ffe           = (ctc_chip_serdes_ffe_t*)p_value;
    ctc_chip_serdes_polarity_t* p_polarity = (ctc_chip_serdes_polarity_t*)p_value;
    ctc_chip_serdes_loopback_t* p_loopback = (ctc_chip_serdes_loopback_t*)p_value;
    ctc_chip_serdes_ctle_t* p_ctle         = (ctc_chip_serdes_ctle_t*)p_value;
    ctc_chip_serdes_cfg_t* p_cfg           = (ctc_chip_serdes_cfg_t*)p_value;
    ctc_chip_serdes_map_cfg_t* p_map       = (ctc_chip_serdes_map_cfg_t*)p_value;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);

    /* user_serdes to physical_serdes */
    if (MCHIP_DMPS(lchip)->serdes_to_psd)
    {
        switch(chip_prop)
        {
            case CTC_CHIP_PROP_SERDES_PRBS:
                serdes_id = p_prbs->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_prbs->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_FFE:
                serdes_id = p_ffe->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_ffe->serdes_id = psd;
                break;
            case CTC_CHIP_PEOP_SERDES_POLARITY:
                serdes_id = p_polarity->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_polarity->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_LOOPBACK:
                serdes_id = p_loopback->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_loopback->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_P_FLAG:
            case CTC_CHIP_PROP_SERDES_PEAK:
            case CTC_CHIP_PROP_SERDES_DPC:
            case CTC_CHIP_PROP_SERDES_SLEW_RATE:
                break;
            case CTC_CHIP_PROP_SERDES_CTLE:
                serdes_id = p_ctle->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_ctle->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_DFE:
                break;
            case CTC_CHIP_PROP_SERDES_MAP:
                for (cnt = 0; cnt < CTC_HSS_SERDES_NUM; cnt++)
                {
                    serdes_id = p_map->serdes_id[cnt];
                    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                    p_map->serdes_id[cnt] = psd;
                }
                break;
            case CTC_CHIP_PROP_SERDES_PRE_CODING:
            case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            case CTC_CHIP_PROP_SERDES_EN:
            case CTC_CHIP_PROP_SERDES_RESET:
                serdes_id = p_cfg->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_cfg->serdes_id = psd;
                break;
            default:
                break;
        }
    }

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_serdes_set_property(lchip, chip_prop, p_value);
    PORT_API_UNLOCK(lchip);

    /* physical_serdes to user_serdes */
    if (MCHIP_DMPS(lchip)->psd_to_serdes)
    {
        switch(chip_prop)
        {
            case CTC_CHIP_PROP_SERDES_PRBS:
                p_prbs->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_FFE:
                p_ffe->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PEOP_SERDES_POLARITY:
                p_polarity->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_LOOPBACK:
                p_loopback->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_P_FLAG:
            case CTC_CHIP_PROP_SERDES_PEAK:
            case CTC_CHIP_PROP_SERDES_DPC:
            case CTC_CHIP_PROP_SERDES_SLEW_RATE:
                break;
            case CTC_CHIP_PROP_SERDES_CTLE:
                p_ctle->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_DFE:
                break;
            case CTC_CHIP_PROP_SERDES_MAP:
                for (cnt = 0; cnt < CTC_HSS_SERDES_NUM; cnt++)
                {
                    psd = p_map->serdes_id[cnt];
                    ret = (CTC_E_NONE != ret) ? ret : (MCHIP_DMPS(lchip)->psd_to_serdes(lchip, psd, &serdes_id));
                    p_map->serdes_id[cnt] = serdes_id;
                }
                break;
            case CTC_CHIP_PROP_SERDES_PRE_CODING:
            case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            case CTC_CHIP_PROP_SERDES_EN:
            case CTC_CHIP_PROP_SERDES_RESET:
                p_cfg->serdes_id = serdes_id;
                break;
            default:
                break;
        }
    }

    return ret;
}

int32
sys_usw_port_api_get_serdes_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    uint16 cnt       = 0;
    uint16 serdes_id = 0;
    uint16 psd       = 0;
    ctc_chip_serdes_prbs_t* p_prbs         = (ctc_chip_serdes_prbs_t*)p_value;
    ctc_chip_serdes_ffe_t* p_ffe           = (ctc_chip_serdes_ffe_t*)p_value;
    ctc_chip_serdes_polarity_t* p_polarity = (ctc_chip_serdes_polarity_t*)p_value;
    ctc_chip_serdes_loopback_t* p_loopback = (ctc_chip_serdes_loopback_t*)p_value;
    ctc_chip_serdes_ctle_t* p_ctle         = (ctc_chip_serdes_ctle_t*)p_value;
    ctc_chip_serdes_cfg_t* p_cfg           = (ctc_chip_serdes_cfg_t*)p_value;
    ctc_chip_serdes_map_cfg_t* p_map       = (ctc_chip_serdes_map_cfg_t*)p_value;
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_value);

    /* user_serdes to physical_serdes */
    if  (MCHIP_DMPS(lchip)->serdes_to_psd)
    {
        switch(chip_prop)
        {
            case CTC_CHIP_PROP_SERDES_PRBS:
                serdes_id = p_prbs->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_prbs->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_FFE:
                serdes_id = p_ffe->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_ffe->serdes_id = psd;
                break;
            case CTC_CHIP_PEOP_SERDES_POLARITY:
                serdes_id = p_polarity->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_polarity->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_LOOPBACK:
                serdes_id = p_loopback->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_loopback->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_P_FLAG:
            case CTC_CHIP_PROP_SERDES_PEAK:
            case CTC_CHIP_PROP_SERDES_DPC:
            case CTC_CHIP_PROP_SERDES_SLEW_RATE:
                break;
            case CTC_CHIP_PROP_SERDES_CTLE:
                serdes_id = p_ctle->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_ctle->serdes_id = psd;
                break;
            case CTC_CHIP_PROP_SERDES_DFE:
                break;
            case CTC_CHIP_PROP_SERDES_MAP:
                for (cnt = 0; cnt < CTC_HSS_SERDES_NUM; cnt++)
                {
                    serdes_id = p_map->serdes_id[cnt];
                    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                    p_map->serdes_id[cnt] = psd;
                }
                break;
            case CTC_CHIP_PROP_SERDES_PRE_CODING:
            case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            case CTC_CHIP_PROP_SERDES_EN:
            case CTC_CHIP_PROP_PLL_LOCK_STATUS:
            case CTC_CHIP_PROP_SERDES_RESET:
                serdes_id = p_cfg->serdes_id;
                CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->serdes_to_psd(lchip, serdes_id, &psd));
                p_cfg->serdes_id = psd;
                break;
            default:
                break;
        }
    }

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_serdes_get_property(lchip, chip_prop, p_value);
    PORT_API_UNLOCK(lchip);

    /* physical_serdes to user_serdes */
    if (!ret && (MCHIP_DMPS(lchip)->psd_to_serdes))
    {
        switch(chip_prop)
        {
            case CTC_CHIP_PROP_SERDES_PRBS:
                p_prbs->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_FFE:
                p_ffe->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PEOP_SERDES_POLARITY:
                p_polarity->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_LOOPBACK:
                p_loopback->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_P_FLAG:
            case CTC_CHIP_PROP_SERDES_PEAK:
            case CTC_CHIP_PROP_SERDES_DPC:
            case CTC_CHIP_PROP_SERDES_SLEW_RATE:
                break;
            case CTC_CHIP_PROP_SERDES_CTLE:
                p_ctle->serdes_id = serdes_id;
                break;
            case CTC_CHIP_PROP_SERDES_DFE:
                break;
            case CTC_CHIP_PROP_SERDES_MAP:
                for (cnt = 0; cnt < CTC_HSS_SERDES_NUM; cnt++)
                {
                    psd = p_map->serdes_id[cnt];
                    CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->psd_to_serdes(lchip, psd, &serdes_id));
                    p_map->serdes_id[cnt] = serdes_id;
                }
                break;
            case CTC_CHIP_PROP_SERDES_PRE_CODING:
            case CTC_CHIP_PROP_SERDES_OPTICAl_MODE:
            case CTC_CHIP_PROP_SERDES_EN:
            case CTC_CHIP_PROP_PLL_LOCK_STATUS:
            case CTC_CHIP_PROP_SERDES_RESET:
                p_cfg->serdes_id = serdes_id;
                break;
            default:
                break;
        }
    }

    return ret;
}

/*
 * uint32 block_id
 *     [15:0]  : start_idx, start entry index per 40 entry of McMacStatsRam 
 *     [17:16] : ram_id, 0 : McMacStatsRam0, 1 : McMacStatsRam1, 2 : QuadSgmacStatsRam (CPU MAC)
 *     [18]    : core_id
 *     [31:19] : rsv 
 */
int32
sys_usw_port_api_get_mac_stats(uint8 lchip, uint32 block_id, sys_usw_dmps_mac_stats_t* p_mac_stats)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mac_stats);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_get_mac_stats(lchip, block_id, p_mac_stats);
    PORT_API_UNLOCK(lchip);
    
    return ret;
}

/*
 * uint32 block_id
 *     [15:0]  : start_idx, start entry index per 40 entry of McMacStatsRam 
 *     [17:16] : ram_id, 0 : McMacStatsRam0, 1 : McMacStatsRam1, 2 : QuadSgmacStatsRam (CPU MAC)
 *     [18]    : core_id
 *     [31:19] : rsv 
 */
int32
sys_usw_port_api_clear_mac_stats(uint8 lchip, uint32 block_id, uint8 dir)
{
    int32 ret = CTC_E_NONE;

    SYS_PORT_INIT_CHECK(lchip);

    PORT_API_LOCK(lchip);
    ret = sys_usw_dmps_clear_mac_stats(lchip, block_id, dir);
    PORT_API_UNLOCK(lchip);
    
    return ret;
}

#define ______PORT_DMPS_DB______
int32
sys_usw_port_api_dmps_dump_db(uint8 lchip, sal_file_t dump_db_fp,ctc_global_dump_db_t* p_dump_param)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_dump_db(lchip, dump_db_fp, p_dump_param);

    return ret;
}

int32
sys_usw_port_api_dmps_wb_sync(uint8 lchip, uint32 app_id)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_wb_sync_master(lchip, app_id);

    return ret;
}

int32
sys_usw_port_api_alloc_chan(uint8 lchip, uint32* p_chan_id)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_chan_id);

    ret = sys_usw_dmps_db_alloc_chan(lchip, p_chan_id);

    return ret;
}

int32
sys_usw_port_api_alloc_port(uint8 lchip, uint32* p_lport)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_lport);

    ret = sys_usw_dmps_db_alloc_port(lchip, p_lport);

    return ret;
}

int32
sys_usw_port_api_get_misc_chan_info(uint8 lchip, uint8 misc_chan_type, sys_port_api_misc_chan_info_t* p_misc_info)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_misc_info);

    ret = sys_usw_dmps_db_get_misc_chan_info(lchip, misc_chan_type, p_misc_info);

    return ret;
}

int32
sys_usw_port_api_set_internal_port_info(uint8 lchip, sys_internal_port_info_t* p_port_info)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_port_info);

    ret = sys_usw_dmps_db_set_internal_port_info(lchip, p_port_info);

    return ret;
}

int32
sys_usw_port_api_get_com_info(uint8 lchip, uint16 lport, uint8 index, sys_port_info_t* p_port_info)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_port_info);

    ret = sys_usw_dmps_db_api_get_com_info(lchip, lport, index, p_port_info);

    return ret;
}

int32
sys_usw_port_api_get_port_info(uint8 lchip, uint16 lport, sys_port_api_dmps_info_t* p_port_info)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_port_info);

    ret = sys_usw_dmps_db_api_get_port_info(lchip, lport, p_port_info);

    return ret;
}

int32
sys_usw_port_api_check_datapath_credit_clear(uint8 lchip, uint32 mac_id, uint32 chan_id)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_port_check_datapath_credit_clear(lchip, mac_id, chan_id);

    return ret;
}

int32
sys_usw_port_api_set_other_misc_chan(uint8 lchip, uint16 lport, uint8 port_type, uint8 speed_mode, uint8 dir)
{
    int32 ret = CTC_E_NONE;

    if ((!CTC_WB_ENABLE(lchip)) || (CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING))
    {
        ret = sys_usw_dmps_port_set_other_misc_chan(lchip, lport, port_type, speed_mode, (CTC_EGRESS == dir) ? CHAN_DIR_TX : CHAN_DIR_RX);
    }

    return ret;
}

int32
sys_usw_port_api_get_chan_by_info(uint8 lchip, uint8 p_core_id, uint8 p_pp_id, uint8 p_dp_id, uint16 index_in_dp, uint16* p_chan_id)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_db_get_chan_by_info(lchip, p_core_id, p_pp_id, p_dp_id, index_in_dp, p_chan_id);

    return ret;
}

int32
sys_usw_port_api_get_internal_chan_start(uint8 lchip, uint8 dp_id, uint16* p_chan_id)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_get_internal_chan_start(lchip, dp_id, p_chan_id);

    return ret;
}

/* p_value must be uint32* if is numerical */
int32
sys_usw_port_api_get_dmps_property(uint8 lchip, sys_usw_dmps_port_info_t* p_dmps_port_info, sys_port_api_dmps_property_t dmps_prop, void *p_value)
{
    int32 ret = CTC_E_NONE;
    uint8 idx = 0;
    uint8 is_network = 0;
    uint8 is_cpumac  = FALSE;
    uint16 tmp_lport = 0;
    sys_dmps_port_info_t port_info = {0};
    sys_dmps_db_cpumac_map_t cpumac_map = {0};

    CTC_PTR_VALID_CHECK(p_value);
    #ifdef EMULATION_ENV
    if(dmps_prop == SYS_PORT_API_DMPS_PROP_PP_ID)
    {
        *(uint32*)p_value = 0;
        return CTC_E_NONE;
    }
    #endif
    port_info.dir_bmp   = p_dmps_port_info->rx ? CHAN_DIR_RX : CHAN_DIR_TX;
    port_info.index   = p_dmps_port_info->index;

    if (CTC_IS_CPU_PORT(p_dmps_port_info->gport) && DRV_FROM_TMM(lchip))
    {
        idx = p_dmps_port_info->gport & 0xf;
        if(MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
        {
            ret = MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,idx,&port_info.lport,&is_network);
        }
    }
    else
    {
        port_info.lport = CTC_MAP_GPORT_TO_LPORT(p_dmps_port_info->gport);
    }

    for (idx = 0; idx < DMPS_MAX_NUM_CPUMAC_MAP; idx ++)
    {
        if(MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
        {
            ret = MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,idx,&tmp_lport, NULL);
            if (port_info.lport == tmp_lport)
            {
                is_cpumac = TRUE;
                break;
            }
        }
    }
 
    if ((SYS_PORT_API_DMPS_PROP_CHAN_ID == dmps_prop) && is_cpumac && DRV_IS_TMG(lchip))
    {
        
        idx = p_dmps_port_info->gport & 0xf;
        ret = sys_usw_dmps_db_get_cpumac_map(lchip, idx, &cpumac_map);

        *(uint32 *)p_value = cpumac_map.chan_id;
        /**(uint32 *)p_value = SYS_USW_CHANNEL_DECODE(*(uint32 *)p_value);  // TODO TMG temp for dmps get chan_id*/
        return ret;
    }
    /* SYS_PORT_API_DMPS_PROP_CHAN_ID get origin channel */
    else if (SYS_PORT_API_DMPS_PROP_CHAN_ID == dmps_prop && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        ret = sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_GET_PMAC_CHAN_ID, p_value);
        if (!ret && (SYS_COMMON_USELESS_CHANNEL == *(uint32 *)p_value))
        {
            ret = sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, p_value);
        }
        return ret;
    }
    else if (SYS_PORT_API_DMPS_PROP_GET_PMAC_CHAN_ID == dmps_prop && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        ret = sys_usw_dmps_db_api_get_port_property(lchip, &port_info, dmps_prop, p_value);
        if (!ret && (SYS_COMMON_USELESS_CHANNEL != *(uint32 *)p_value))
        {
            ret = sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, p_value);
        }
        return ret;
    }

    switch (dmps_prop)
    {
    case SYS_PORT_API_DMPS_PROP_EN:
        ret = sys_usw_dmps_get_mac_property(lchip, port_info.lport, CTC_PORT_PROP_MAC_EN, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_LINK_UP:
        ret = sys_usw_dmps_get_mac_property(lchip, port_info.lport, CTC_PORT_PROP_LINK_UP, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_TX_IPG:
        ret = sys_usw_dmps_get_mac_property(lchip, port_info.lport, CTC_PORT_PROP_MAC_TX_IPG, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_XPIPE_RX:
        ret = sys_usw_dmps_get_mac_property(lchip, port_info.lport, CTC_PORT_PROP_XPIPE_EN, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_XPIPE_TX:
        ret = sys_usw_dmps_get_mac_property(lchip, port_info.lport, CTC_PORT_PROP_XPIPE_MODE, (uint32*)p_value);
        break;
    case SYS_PORT_API_DMPS_PROP_SFD_ENABLE:
        ret = sys_usw_dmps_get_sfd_en(lchip, port_info.lport, (uint32*)p_value);
        break;
    default:
        ret = sys_usw_dmps_db_api_get_port_property(lchip, &port_info, dmps_prop, p_value);
        break;
    }

    return ret;
}

uint16
sys_usw_port_api_get_lport_with_chan(uint8 lchip, uint8 rx, uint16 chan_id)
{
    uint16 lport   = 0;
    uint8  dir_bmp = rx ? CHAN_DIR_RX : CHAN_DIR_TX;

    lport = sys_usw_dmps_db_api_get_lport_with_chan(lchip, dir_bmp, chan_id);

    return lport;
}

uint16
sys_usw_port_api_get_lport_with_subchan(uint8 lchip, uint8 rx, uint8 core, uint8 pp, uint8 dp, uint8 sub_chan_id)
{
    uint16 lport  = 0;
    uint8 dir_bmp = rx ? CHAN_DIR_RX : CHAN_DIR_TX;

    lport = sys_usw_dmps_db_api_get_lport_with_subchan(lchip, dir_bmp, core, pp, dp, sub_chan_id);

    return lport;
}

uint16
sys_usw_port_api_get_lport_with_mac(uint8 lchip, uint16 mac_id)
{
    uint16 lport = 0;

    SYS_PORT_INIT_CHECK(lchip);

    lport = sys_usw_dmps_db_api_get_lport_with_mac(lchip, mac_id);

    return lport;
}

int32
sys_usw_port_api_get_sub_chan_by_chan(uint8 lchip, uint8 rx, uint16 chan, uint16* sub_chan, uint8* pp_id, uint8* dp_id)
{
    uint8 ret = CTC_E_NONE;
    uint8 dir_bmp = rx ? CHAN_DIR_RX : CHAN_DIR_TX;

    CTC_PTR_VALID_CHECK(sub_chan);
    CTC_PTR_VALID_CHECK(pp_id);
    CTC_PTR_VALID_CHECK(dp_id);

    ret = sys_usw_dmps_db_api_get_sub_chan_by_chan(lchip, dir_bmp, chan, sub_chan, pp_id, dp_id);

    return ret;
}

int32
sys_usw_port_api_get_mac_group_valid(uint8 lchip, uint8 core_id, uint32* p_mac_group_valid)
{
    int32 ret = CTC_E_NONE;

    CTC_PTR_VALID_CHECK(p_mac_group_valid);

    ret = sys_usw_dmps_db_get_mac_group_valid(lchip, core_id, p_mac_group_valid);

    return ret;
}

int32
sys_usw_port_misc_chan_init(uint8 lchip)
{
    uint16 index = 0;
    uint8 gchip = 0;
    uint16 lport_idx = 0;
    sys_internal_port_info_t port_info;

    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        return CTC_E_NONE;
    }

    sal_memset(&port_info, 0, sizeof(sys_internal_port_info_t));
    sys_usw_get_gchip_id(lchip, &gchip);
    /*iloop port*/
    for (index=0; index<sys_usw_vchip_get_pp_num(lchip); index++)
    {
        if(DRV_IS_AT(lchip))
        {
            if ((SYS_RSV_PORT_ILOOP_ID-lport_idx) == SYS_RSV_PORT_SPINE_LEAF_PORT)
            {
                /*need ignore spine leaf port*/
                lport_idx++;
            }
            port_info.lport = SYS_RSV_PORT_ILOOP_ID-lport_idx;
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP)+index*2;
            port_info.pp_id = index;
            port_info.dp_id = 0;
            port_info.sub_chan_id = SYS_DMPS_LOOP_SUB_CHAN;
            port_info.speed_mode = SYS_PORT_SPEED_200G;
            port_info.port_type = SYS_DMPS_ILOOP_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP)+index*2+1;
            port_info.dp_id = 1;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ILOOP)+index*2));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ILOOP)+index*2+1));
            (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_ILOOP_ID-lport_idx));
            lport_idx++;
        }
        else if(DRV_IS_TMG(lchip))
        {
            port_info.lport = SYS_RSV_PORT_ILOOP_ID;
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP); //54
            port_info.pp_id = index;
            port_info.dp_id = 0;
            port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
            port_info.speed_mode = CTC_PORT_SPEED_200G;
            port_info.port_type = SYS_DMPS_ILOOP_PORT;
            port_info.dp_mac_client = 82;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); //54 + 64
            port_info.dp_id = 1;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ILOOP)));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ILOOP) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM)));
            (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_ILOOP_ID));
            /*(void)(sys_usw_port_set_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, port_info.lport), CTC_PORT_PROP_QOS_POLICY, CTC_QOS_TRUST_OUTER));*/
        }
    }

    /*eloop port*/
    for (index=0; index<sys_usw_vchip_get_pp_num(lchip); index++)
    {
        if(DRV_IS_AT(lchip))
        {
            port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_ELOOP_ID)-index;
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ELOOP)+index*2;
            port_info.pp_id = index;
            port_info.dp_id = 0;
            port_info.sub_chan_id = SYS_DMPS_LOOP_SUB_CHAN;
            port_info.speed_mode = SYS_PORT_SPEED_200G;
            port_info.port_type = SYS_DMPS_ELOOP_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP)+index*2+1;
            port_info.dp_id = 1;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ELOOP)+index*2));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ELOOP)+index*2+1));
            (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_ELOOP_ID)-index));
        }
        else if(DRV_IS_TMG(lchip))
        {
            port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_ELOOP_ID);
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ELOOP); //54
            port_info.pp_id = index;
            port_info.dp_id = 0;
            port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_ELOOP) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
            port_info.speed_mode = CTC_PORT_SPEED_200G;
            port_info.port_type = SYS_DMPS_ELOOP_PORT;
            port_info.dp_mac_client = 82;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_ELOOP) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM); //54 + 64
            port_info.dp_id = 1;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ELOOP)));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_ELOOP) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM)));
            (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_ELOOP_ID)));
            /*(void)(sys_usw_port_set_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, port_info.lport), CTC_PORT_PROP_QOS_POLICY, CTC_QOS_TRUST_OUTER));*/
        }
    }

    /*drop port*/
    if(DRV_IS_AT(lchip))
    {
        port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_DROP_ID);
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_DROP);
        port_info.pp_id = 0;
        port_info.dp_id = 0;
        port_info.sub_chan_id = SYS_DMPS_INVALID_SUB_CHAN_ID;
        port_info.speed_mode = SYS_PORT_SPEED_1G;
        port_info.port_type = SYS_DMPS_MISC_OTHER_PORT;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_DROP)));
        (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_DROP_ID)));
    }
    else if(DRV_IS_TMG(lchip))
    {
        port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_DROP_ID);
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_DROP); //63
        port_info.pp_id = 0;
        port_info.dp_id = 0;
        port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_DROP) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
        port_info.speed_mode = CTC_PORT_SPEED_MAX;
        port_info.port_type = SYS_DMPS_MISC_OTHER_PORT;
        port_info.dp_mac_client = DMPS_INVALID_VALUE_U16;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_DROP)));
        (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_DROP_ID)));
    }
    if(DRV_IS_AT(lchip))
    {
    /*oam port*/
        port_info.lport = SYS_RSV_PORT_OAM_CPU_ID;
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_OAM);
        port_info.pp_id = 2;
        port_info.dp_id = 1;
        port_info.sub_chan_id = SYS_DMPS_MISC_SUB_CHAN;
        port_info.speed_mode = SYS_PORT_SPEED_50G;
        port_info.port_type = SYS_DMPS_OAM_PORT;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_OAM)));
        (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_OAM_CPU_ID));

        /*oam port1*/
        if (2 == drv_vchip_get_core_num(lchip) && MCHIP_FEATURE_PP_EN(lchip, CTC_FEATURE_OAM))
        {
            port_info.lport = SYS_RSV_PORT_OAM_CPU1_ID;
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_OAM1);
            port_info.pp_id = SYS_CORE_PP_NUM(lchip) + 2;
            port_info.dp_id = 1;
            port_info.sub_chan_id = SYS_DMPS_MISC_SUB_CHAN;
            port_info.speed_mode = SYS_PORT_SPEED_50G;
            port_info.port_type = SYS_DMPS_OAM_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_OAM1)));
            (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_OAM_CPU1_ID));
        }
    }
    else if(DRV_IS_TMG(lchip))
    {
        /*oam port*/
        port_info.lport = SYS_RSV_PORT_OAM_CPU_ID;
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_OAM); //55
        port_info.pp_id = 0;
        port_info.dp_id = 1;
        port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_OAM) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
        port_info.speed_mode = CTC_PORT_SPEED_50G;
        port_info.port_type = SYS_DMPS_OAM_PORT;
        port_info.dp_mac_client = 83;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_OAM)));
        (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_OAM_CPU_ID));
        /*(void)(sys_usw_port_set_property(lchip, CTC_MAP_LPORT_TO_GPORT(gchip, port_info.lport), CTC_PORT_PROP_QOS_POLICY, CTC_QOS_TRUST_OUTER));*/
    }

    /*dma port*/
    for (index=0; index<sys_usw_vchip_get_pp_num(lchip); index++)
    {
        if(DRV_IS_AT(lchip))
        {
            if (1 == (index % SYS_CORE_PP_NUM(lchip)) || 2 == (index % SYS_CORE_PP_NUM(lchip)))
            {
                continue;
            }
            port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_TO_CPU);
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0)+index;
            port_info.pp_id = index;
            port_info.dp_id = 0;
            port_info.sub_chan_id = SYS_DMPS_MISC_SUB_CHAN;
            port_info.speed_mode = SYS_PORT_SPEED_10G;
            port_info.port_type = SYS_DMPS_DMA_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0)+index));
        }
        else if(DRV_IS_TMG(lchip))
        {
            port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_TO_CPU);
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0); //56
            port_info.pp_id = 0;
            port_info.dp_id = 0;
            port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
            port_info.speed_mode = CTC_PORT_SPEED_10G;
            port_info.port_type = SYS_DMPS_DMA_PORT;
            port_info.dp_mac_client = 84;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0)));
        }
    }
    (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_TO_CPU)));

    /*eunit channel*/
    if(DRV_IS_AT(lchip))
    {
        for (index=0; index < MCHIP_CAP(SYS_CAP_CPU_REASON_GRP_NUM_EUNIT); index++)
        {
            port_info.lport = SYS_DMPS_INVALID_CHAN_ID;
            port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_EUNIT0) + index;
            if (SYS_VCHIP_DUAL_CORE_MODE(lchip) && index >= (MCHIP_CAP(SYS_CAP_CPU_REASON_GRP_NUM_EUNIT) / drv_vchip_get_core_num(lchip)))
            {
                port_info.pp_id = 1 + index - (MCHIP_CAP(SYS_CAP_CPU_REASON_GRP_NUM_EUNIT) / drv_vchip_get_core_num(lchip)) + (SYS_PP_NUM(lchip) / drv_vchip_get_core_num(lchip));
                /*core0 pp1 pp2 & core1 pp1 pp2 dp 0 sub_channel 24 for eunit*/
            }
            else
            {
                port_info.pp_id = 1 + index; /*core0 pp1 pp2 dp 0 sub_channel 24 for eunit*/
            }
            port_info.dp_id = 0;
            port_info.sub_chan_id = SYS_DMPS_MISC_SUB_CHAN;
            port_info.speed_mode = SYS_PORT_SPEED_50G;
            port_info.port_type = SYS_DMPS_DMA_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_EUNIT0) + index));
        }

        port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_E2ILOOP_ID);
        port_info.chan_id = DMPS_INVALID_VALUE_U16;
        port_info.pp_id = DMPS_INVALID_VALUE_U8;
        port_info.dp_id = DMPS_INVALID_VALUE_U8;
        port_info.sub_chan_id = DMPS_INVALID_VALUE_U16;
        port_info.speed_mode = CTC_PORT_SPEED_MAX;
        port_info.port_type = SYS_DMPS_RSV_PORT;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_chan(lchip, DMPS_INVALID_VALUE_U16));
        (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_E2ILOOP_ID)));

        port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_BYPASS_IPE_ID);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_BYPASS_IPE_ID)));

        port_info.lport = MCHIP_CAP(SYS_CAP_RSV_PORT_START);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_port(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_START)));
    }
    else if(DRV_IS_TMG(lchip))
    {
        port_info.lport = SYS_RSV_PORT_EUNIT0_ID;
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_EUNIT0); //56 + 64
        port_info.pp_id = 0;
        port_info.dp_id = 0;
        port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_EUNIT0) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
        port_info.speed_mode = CTC_PORT_SPEED_1G;
        port_info.port_type = SYS_DMPS_DMA_PORT;
        port_info.dp_mac_client = 84;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_EUNIT0_ID));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_EUNIT0)));
        port_info.lport = SYS_RSV_PORT_EUNIT1_ID;
        port_info.chan_id = MCHIP_CAP(SYS_CAP_CHANID_EUNIT1); //57 + 64
        port_info.pp_id = 0;
        port_info.dp_id = 0;
        port_info.sub_chan_id = MCHIP_CAP(SYS_CAP_CHANID_EUNIT1) % MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM);
        port_info.speed_mode = CTC_PORT_SPEED_1G;
        port_info.port_type = SYS_DMPS_DMA_PORT;
        port_info.dp_mac_client = 85;
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
        (void)(sys_usw_dmps_db_assign_port(lchip, SYS_RSV_PORT_EUNIT0_ID));
        (void)(sys_usw_dmps_db_assign_chan(lchip, MCHIP_CAP(SYS_CAP_CHANID_EUNIT0)));
    }

    return CTC_E_NONE;
}

int32
sys_usw_port_api_dmps_db_init(uint8 lchip)
{
    int32 ret = CTC_E_NONE;

    ret = sys_usw_dmps_db_init(lchip);
    ret = ret?ret:sys_usw_port_misc_chan_init(lchip);
    return ret;
}

int32
sys_usw_port_api_dmps_db_deinit(uint8 lchip)
{
    sys_usw_dmps_db_deinit(lchip);
    return CTC_E_NONE;
}

/*since AT*/
void
sys_usw_port_api_dmps_daemon_thread(void* para)
{
    uint8  lchip     = (uintptr)para;
    uint16 lport     = 0;
    uint32 gap_ms    = 800;
    uint32 daemon_en = FALSE;
    uint32 rsthw_en  = FALSE;

    SYS_LCHIP_CHECK_ACTIVE_START_THREAD(lchip);

    while(1)
    {
        _sys_usw_dmps_get_daemon_gap_ms(lchip, &gap_ms);

        for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
        {
            SYS_LCHIP_CHECK_ACTIVE_IN_THREAD(lchip);
            SYS_CHIP_CHECK_RESET_HW_IN_THREAD(lchip);
            if(CTC_E_NONE != sys_usw_peri_get_property(lchip, CTC_CHIP_PROP_RESET_HW, (void*)(&rsthw_en)))
            {
                continue;
            }
            if(rsthw_en)
            {
                continue;
            }
            
            (void)_sys_usw_dmps_get_daemon_en(lchip, &daemon_en);
            SYS_CONDITION_CONTINUE(FALSE == daemon_en);

            PORT_API_LOCK(lchip);

            sys_usw_dmps_daemon_thread(lchip, lport);
            
            PORT_API_UNLOCK(lchip);
            
            sal_task_sleep(1);
        }

        sal_task_sleep(gap_ms);
    }

    return;
}

void
sys_usw_port_api_dmps_msg_rcv_thread(void* para)
{
    uint8 lchip  = (uintptr)para;
    uint8 mcu_id = 0;
    int32 ret    = CTC_E_NONE;
    sys_dmps_db_msg_handle_t* p_handle = NULL;

    (void)sys_usw_dmps_db_get_msg_handle(lchip, &p_handle);

    if (NULL == p_handle)
    {
        return;
    }
    
    SYS_LCHIP_CHECK_ACTIVE_START_THREAD(lchip);

    while(1)
    {
        SYS_LCHIP_CHECK_ACTIVE_IN_THREAD(lchip);
        SYS_CHIP_CHECK_RESET_HW_IN_THREAD(lchip);

        ret = sal_sem_take(p_usw_mac_master[lchip]->p_dmps_msg_sem, 1);
        if (0 != ret)
        {
            continue;
        }
        
        for (mcu_id = 0; mcu_id < p_handle->mcu_info.max_mcu_num; mcu_id++)
        {   
            if (!CTC_BMP_ISSET(p_handle->mcu_info.mcu_bmp, mcu_id))
            {
                continue;
            }

            PORT_API_LOCK(lchip);
            (void)sys_usw_dmps_msg_recv(lchip, mcu_id);
            PORT_API_UNLOCK(lchip);
        }
    }  

    return;
}

/*since AT*/
int32
_sys_usw_port_api_dmps_thread_register(uint8 lchip)
{
    drv_work_platform_type_t platform_type;
    int32   ret      = 0;
    uintptr chip_id  = lchip;
    uint64  cpu_mask = sys_usw_chip_get_affinity(lchip, 0);
    
    SYS_CONDITION_RETURN(SYS_VCHIP_PP_IS_NOT_BASE(lchip), CTC_E_NONE);
    SYS_CONDITION_RETURN(sys_usw_chip_get_reset_hw_en(lchip), CTC_E_NONE);

    CTC_ERROR_RETURN(drv_get_platform_type(lchip, &platform_type));
    SYS_CONDITION_RETURN(platform_type != HW_PLATFORM, CTC_E_NONE);

    /*init log area*/
    sal_memset(p_usw_mac_master[lchip]->scan_log, 0, sizeof(sys_usw_scan_log_t)*SYS_PORT_MAX_LOG_NUM);
    p_usw_mac_master[lchip]->cur_log_index = 0;

    /*DMPS CPU-MCU message receive thread*/
    ret = sal_sem_create(&(p_usw_mac_master[lchip]->p_dmps_msg_sem), 0);
    if (ret < 0)
    {
        return CTC_E_NOT_INIT;
    }
    ret = sys_usw_task_create(lchip,&(p_usw_mac_master[lchip]->p_dmps_msg_rcv), "ctcDmpsMsgMon",
                          SAL_DEF_TASK_STACK_SIZE, SAL_TASK_PRIO_DEF, SAL_TASK_TYPE_LINK_SCAN,
                          cpu_mask, sys_usw_port_api_dmps_msg_rcv_thread, (void*)chip_id);
    if (ret < 0)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Feature not initialized! ctcDmpsMsgMon\n");
        return CTC_E_NOT_INIT;
    }

    /*Daemon thread, e.g. link monitor*/
    ret = sys_usw_task_create(lchip,&(p_usw_mac_master[lchip]->p_monitor_scan), "ctclnkMon",
                          SAL_DEF_TASK_STACK_SIZE, SAL_TASK_PRIO_DEF, SAL_TASK_TYPE_LINK_SCAN, 
                          cpu_mask, sys_usw_port_api_dmps_daemon_thread, (void*)chip_id);
    if (ret < 0)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Feature not initialized! ctclnkMon\n");
        return CTC_E_NOT_INIT;
    }

    /*p_usw_mac_master[lchip]->polling_status = 1;*/
    CTC_ERROR_RETURN(_sys_usw_dmps_set_daemon_en(lchip, 1));
    /*set default time gap 800ms*/
    CTC_ERROR_RETURN(_sys_usw_dmps_set_daemon_gap_ms(lchip, 800));

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_port_api_dmps_thread_destroy(uint8 lchip)
{
    drv_work_platform_type_t platform_type;

    CTC_ERROR_RETURN(drv_get_platform_type(lchip, &platform_type));
    SYS_CONDITION_RETURN(platform_type != HW_PLATFORM, CTC_E_NONE);
    
    SYS_CONDITION_RETURN(SYS_VCHIP_PP_IS_NOT_BASE(lchip), CTC_E_NONE);
    
    /*DMPS CPU-MCU message receive thread*/
    sal_task_destroy(p_usw_mac_master[lchip]->p_dmps_msg_rcv);
    sal_sem_destroy(p_usw_mac_master[lchip]->p_dmps_msg_sem);
    
    /*Daemon thread, e.g. link monitor*/
    sal_task_destroy(p_usw_mac_master[lchip]->p_monitor_scan);
    
    return CTC_E_NONE;
}

int32
sys_usw_port_api_mac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data)
{
    uint8  link_intr = FALSE;
    uint8  gchip_id  = 0;
    uint8  port_num  = 1;
    uint8  loop_idx  = 0;
    int32  ret       = CTC_E_NONE;
    CTC_INTERRUPT_EVENT_FUNC cb = NULL;
    ctc_port_link_status_t   port_link_status[8];

    PORT_API_LOCK(lchip);
    sal_memset(port_link_status, 0, sizeof(ctc_port_link_status_t)*8);
    ret = _sys_usw_dmps_mac_isr_dispatch(lchip, intr, p_data, &link_intr, port_link_status);

    PORT_API_UNLOCK(lchip);

    if (CTC_E_NONE != ret)
    {
        return ret;
    }

    if (link_intr)
    {
        if(DRV_IS_AT(lchip))
        {
            port_num = link_intr;
        }
        CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_PORT_LINK_CHANGE, &cb));
        if (cb)
        {
            CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));
            for (loop_idx = 0; loop_idx < port_num; loop_idx ++)
            {
                cb(gchip_id, &port_link_status[loop_idx]);
            }
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_port_api_cpumac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data)
{
    uint8  link_intr = FALSE;
    uint8  gchip_id  = 0;
    uint8  port_num  = 1;
    uint8  loop_idx  = 0;
    int32  ret       = CTC_E_NONE;
    CTC_INTERRUPT_EVENT_FUNC cb = NULL;
    ctc_port_link_status_t   port_link_status[4];

    PORT_API_LOCK(lchip);
    sal_memset(port_link_status, 0, sizeof(ctc_port_link_status_t)*4);
    ret = _sys_usw_dmps_cpumac_isr_dispatch(lchip, intr, p_data, &link_intr, port_link_status);

    PORT_API_UNLOCK(lchip);

    if (CTC_E_NONE != ret)
    {
        return ret;
    }

    if (link_intr)
    {
        if(DRV_IS_AT(lchip))
        {
            port_num = link_intr;
        }
        CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_PORT_LINK_CHANGE, &cb));
        if (cb)
        {
            CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));
            for (loop_idx = 0; loop_idx < port_num; loop_idx ++)
            {
                cb(gchip_id, &port_link_status[loop_idx]);
            }
        }
    }

    return CTC_E_NONE;
}

/*since AT*/
int32
_sys_usw_port_api_dmps_intr_register(uint8 lchip)
{
    SYS_CONDITION_RETURN(SYS_VCHIP_PP_IS_NOT_BASE(lchip), CTC_E_NONE);
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_MAC, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_CPU_MAC, sys_usw_port_api_cpumac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_MISC_EVENT, sys_usw_port_api_cpumac_isr_dispatch));

    return CTC_E_NONE;
}

int32
_sys_usw_dmps_reset_hw_datapath_proc(uint8 lchip, void* p_data)
{
    int32 ret = CTC_E_NONE;
    uint32 daemon_en = 0;
    ctc_datapath_global_cfg_t* global_cfg = NULL;
    sys_datapath_lport_attr_chip_recover_t* p_port_attr = NULL;

    MALLOC_ZERO(MEM_DMPS_MODULE, global_cfg, sizeof(ctc_datapath_global_cfg_t));

    if(NULL == global_cfg)
    {
        return CTC_E_NO_MEMORY;
    }

    if(SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_datapath_chip_reset_recover_proc(lchip, p_data), ret, error_out);
    }
    else
    {
        if(lchip == drv_vchip_get_pp_base(lchip))
        {
            /*1. rebuild datapath init config.txt*/
            CTC_ERROR_GOTO(sys_usw_dmps_db_get_glbcfg_from_db(lchip, global_cfg), ret, error_out);

            /*2. disable dmps daemon*/
            CTC_ERROR_GOTO(_sys_usw_dmps_get_daemon_en(lchip, &daemon_en), ret, error_out);
            if(FALSE != daemon_en)
            {
                CTC_ERROR_GOTO(_sys_usw_dmps_set_daemon_en(lchip, FALSE), ret, error_out);
            }

            /*3. restore db*/
            MALLOC_ZERO(MEM_SYSTEM_MODULE, p_port_attr, DMPS_MAX_PORT_NUM * sizeof(sys_datapath_lport_attr_chip_recover_t));
            if(p_port_attr == NULL)
            {
                return CTC_E_NO_MEMORY;
            }
            CTC_ERROR_GOTO(_sys_usw_dmps_reset_hw_port_attr_restore(lchip, (void*)p_port_attr), ret, error_out);
        }

        /*4. datapath, db de-init*/
        CTC_ERROR_GOTO(sys_usw_datapath_deinit(lchip), ret, error_out);
        CTC_ERROR_GOTO(sys_usw_port_api_dmps_db_deinit(lchip), ret, error_out);

        /*5. datapath, db init*/
        CTC_ERROR_GOTO(sys_usw_port_api_dmps_db_init(lchip), ret, error_out);
        CTC_ERROR_GOTO(sys_usw_datapath_init(lchip, global_cfg), ret, error_out);

        /*only for base pp*/
        if(lchip == drv_vchip_get_pp_base(lchip))
        {
            /*6. mac reconfig, there are many control variables in the p_usw_mac_master, cannot use sys_usw_mac_deinit*/
            if(MCHIP_DMPS(lchip)->mac_init)
            {
                CTC_ERROR_GOTO(MCHIP_DMPS(lchip)->mac_init(lchip), ret, error_out);
            }

            /*7. recover db*/
            CTC_ERROR_GOTO(_sys_usw_dmps_reset_hw_port_attr_recover(lchip, (void*)p_port_attr), ret, error_out);

            /*8. enable dmps daemon*/
            _sys_usw_dmps_reset_hw_clear_link_fsm(lchip);
            if(FALSE != daemon_en)
            {
                CTC_ERROR_GOTO(_sys_usw_dmps_set_daemon_en(lchip, TRUE), ret, error_out);
            }

            /*9. other misc chan init*/
            (void)sys_usw_port_api_set_other_misc_chan(lchip, MCHIP_CAP(SYS_CAP_RSV_PORT_MOD_ID), SYS_DMPS_MISC_OTHER_PORT, SYS_PORT_SPEED_50G, CTC_EGRESS);
        }

        CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_DATAPATH, SYS_WB_APPID_DMPS_SUBID_MAX, sys_usw_port_api_dmps_wb_sync), ret, error_out);
        CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_DATAPATH, sys_usw_port_api_dmps_dump_db), ret, error_out);
    }

error_out:
    if(global_cfg)
    {
        mem_free(global_cfg);
    }
    if(p_port_attr)
    {
        mem_free(p_port_attr);
    }

    return ret;
}

/**
 @brief Initialize the port module
*/
int32
sys_usw_port_api_init(uint8 lchip, ctc_port_global_cfg_t* p_port_global_cfg)
{
    int32  ret = CTC_E_NONE;

    CTC_MAX_VALUE_CHECK(p_port_global_cfg->default_logic_port_en, 1);
    CTC_MAX_VALUE_CHECK(p_port_global_cfg->isolation_group_mode, CTC_ISOLATION_GROUP_MODE_16);
    CTC_MAX_VALUE_CHECK(p_port_global_cfg->use_isolation_id, 1);
    LCHIP_CHECK(lchip);

    CTC_ERROR_GOTO(sys_usw_port_init(lchip, p_port_global_cfg), ret, rollback_0);
    CTC_ERROR_GOTO(sys_usw_phy_init(lchip, p_port_global_cfg), ret, rollback_0);
    CTC_ERROR_GOTO(sys_usw_dmps_init(lchip, p_port_global_cfg), ret, rollback_1);

    if (NULL != p_usw_port_api_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_INIT(lchip, p_usw_port_api_master, CTC_FEATURE_PORT);

    /*alloc&init DB and mutex*/
    p_usw_port_api_master[lchip] = (sys_port_api_master_t*)mem_malloc(MEM_PORT_MODULE, sizeof(sys_port_api_master_t));
    if (NULL == p_usw_port_api_master[lchip])
    {
        SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_usw_port_api_master[lchip], 0, sizeof(sys_port_api_master_t));

    ret = sal_mutex_create(&(p_usw_port_api_master[lchip]->p_port_mutex));
    if (ret || !(p_usw_port_api_master[lchip]->p_port_mutex))
    {
        SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Create mutex fail\n");
        goto rollback_2;
    }

    if(!SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        CTC_ERROR_GOTO(_sys_usw_port_api_dmps_thread_register(lchip), ret, rollback_3);
        CTC_ERROR_GOTO(_sys_usw_port_api_dmps_intr_register(lchip), ret, rollback_3);

        CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_DATAPATH, SYS_WB_APPID_DMPS_SUBID_MAX, sys_usw_port_api_dmps_wb_sync), ret, rollback_3);
        CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_DATAPATH, sys_usw_port_api_dmps_dump_db), ret, rollback_3);
    }

#ifndef EMULATION_ENV
    /* MDIO init */
    CTC_ERROR_GOTO(sys_usw_mdio_init(lchip), ret, rollback_3);
#endif
    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_PORT,SYS_WB_APPID_PORT_SUBID_MAX, sys_usw_port_api_wb_sync), ret, rollback_3);
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_PORT, sys_usw_port_api_dump_db), ret, rollback_3);

    return CTC_E_NONE;

rollback_3:
    sal_mutex_destroy(p_usw_port_api_master[lchip]->p_port_mutex);
rollback_2:
    mem_free(p_usw_port_api_master[lchip]);
    p_usw_port_api_master[lchip] = NULL;
rollback_1:
    sys_usw_phy_deinit(lchip);
rollback_0:
    sys_usw_port_deinit(lchip);
    return ret;
}

/**
 @brief De-Initialize port module
*/
int32
sys_usw_port_api_deinit(uint8 lchip)
{
    LCHIP_CHECK(lchip);
    if (NULL == p_usw_port_api_master[lchip])
    {
        SYS_PORT_API_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " port module not init\n");
        return CTC_E_NONE;
    }

    if(!SYS_USW_DMPS_IS_OLD_DB(lchip))
    {
        (void)_sys_usw_port_api_dmps_thread_destroy(lchip);
    }
    sys_usw_dmps_deinit(lchip);
    sys_usw_phy_deinit(lchip);
    sys_usw_port_deinit(lchip);

    if (SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        p_usw_port_api_master[lchip] = NULL;
        return CTC_E_NONE;
    }

    sal_mutex_destroy(p_usw_port_api_master[lchip]->p_port_mutex);

    mem_free(p_usw_port_api_master[lchip]);
    p_usw_port_api_master[lchip] = NULL;

    return CTC_E_NONE;
}
